134709573Sraf /*
234709573Sraf  * CDDL HEADER START
334709573Sraf  *
434709573Sraf  * The contents of this file are subject to the terms of the
534709573Sraf  * Common Development and Distribution License (the "License").
634709573Sraf  * You may not use this file except in compliance with the License.
734709573Sraf  *
834709573Sraf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
934709573Sraf  * or http://www.opensolaris.org/os/licensing.
1034709573Sraf  * See the License for the specific language governing permissions
1134709573Sraf  * and limitations under the License.
1234709573Sraf  *
1334709573Sraf  * When distributing Covered Code, include this CDDL HEADER in each
1434709573Sraf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1534709573Sraf  * If applicable, add the following below this CDDL HEADER, with the
1634709573Sraf  * fields enclosed by brackets "[]" replaced with your own identifying
1734709573Sraf  * information: Portions Copyright [yyyy] [name of copyright owner]
1834709573Sraf  *
1934709573Sraf  * CDDL HEADER END
2034709573Sraf  */
2134709573Sraf 
2234709573Sraf /*
23*7257d1b4Sraf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2434709573Sraf  * Use is subject to license terms.
2534709573Sraf  */
2634709573Sraf 
2734709573Sraf #ifndef	_SIGEV_THREAD_H
2834709573Sraf #define	_SIGEV_THREAD_H
2934709573Sraf 
3034709573Sraf #ifdef	__cplusplus
3134709573Sraf extern "C" {
3234709573Sraf #endif
3334709573Sraf 
3434709573Sraf #include <signal.h>
3534709573Sraf #include <port.h>
3634709573Sraf #include <mqueue.h>
3734709573Sraf #include <time.h>
3834709573Sraf #include <limits.h>
3934709573Sraf #include <semaphore.h>
40f841f6adSraf #include <thread_pool.h>
4134709573Sraf 
4234709573Sraf #define	SIGEV_THREAD_TERM	1
4334709573Sraf 
4434709573Sraf typedef enum {TIMER = 1, MQ, AIO} subsystem_t;	/* Calling sub-system */
4534709573Sraf 
4634709573Sraf typedef struct {
4734709573Sraf 	void (*std_func)(union sigval);	/* User-defined notification function */
4834709573Sraf 	union sigval std_arg;	/* Parameter of user-defined notification fct */
4934709573Sraf } sigev_thread_data_t;
5034709573Sraf 
5134709573Sraf typedef struct thread_communication_data {
5234709573Sraf 	struct thread_communication_data *tcd_next;
5334709573Sraf 	struct sigevent	tcd_notif;	/* encapsulates usr fct and usr vals */
5434709573Sraf 	pthread_attr_t	tcd_user_attr;	/* copy of caller's attributes */
5534709573Sraf 	pthread_attr_t	*tcd_attrp;	/* NULL if caller passed NULL */
5634709573Sraf 	int		tcd_port;	/* port this spawner is controlling */
5734709573Sraf 	thread_t	tcd_server_id;	/* thread id of server thread */
5834709573Sraf 	subsystem_t	tcd_subsystem;	/* event generating subsystem */
5934709573Sraf 	tpool_t		*tcd_poolp;	/* worker thread pool */
6034709573Sraf 	/* for creation/termination synchronization protocol */
6134709573Sraf 	mutex_t		tcd_lock;
6234709573Sraf 	cond_t		tcd_cv;
6334709573Sraf 	/* subsystem-specific data */
6434709573Sraf 	union {
6534709573Sraf 		struct {
6634709573Sraf 			int	overruns;	/* number of overruns */
6734709573Sraf 		} timer;
6834709573Sraf 		struct {
6934709573Sraf 			int	msg_enabled;	/* notification enabled */
7034709573Sraf 			int	msg_closing;	/* mq_close() is waiting */
7134709573Sraf 			sem_t	*msg_avail;	/* wait for message available */
7234709573Sraf 			void	*msg_object;	/* mqd_t */
7334709573Sraf 			void	*msg_userval;	/* notification user value */
7434709573Sraf 		} mqueue;
7534709573Sraf 	} tcd_object;
7634709573Sraf } thread_communication_data_t;
7734709573Sraf 
7834709573Sraf #define	tcd_overruns	tcd_object.timer.overruns
7934709573Sraf 
8034709573Sraf #define	tcd_msg_enabled	tcd_object.mqueue.msg_enabled
8134709573Sraf #define	tcd_msg_closing	tcd_object.mqueue.msg_closing
8234709573Sraf #define	tcd_msg_avail	tcd_object.mqueue.msg_avail
8334709573Sraf #define	tcd_msg_object	tcd_object.mqueue.msg_object
8434709573Sraf #define	tcd_msg_userval	tcd_object.mqueue.msg_userval
8534709573Sraf 
8634709573Sraf /* Generic functions common to all entities */
8734709573Sraf extern thread_communication_data_t *setup_sigev_handler(
8834709573Sraf 		const struct sigevent *, subsystem_t);
8934709573Sraf extern void free_sigev_handler(thread_communication_data_t *);
9034709573Sraf extern int launch_spawner(thread_communication_data_t *);
91f841f6adSraf extern void tcd_teardown(thread_communication_data_t *);
9234709573Sraf 
9334709573Sraf /* Additional functions for different entities */
9434709573Sraf extern void *timer_spawner(void *);
9534709573Sraf extern int del_sigev_timer(timer_t);
9634709573Sraf extern int sigev_timer_getoverrun(timer_t);
9734709573Sraf extern void *mqueue_spawner(void *);
9834709573Sraf extern void del_sigev_mq(thread_communication_data_t *);
9934709573Sraf extern void *aio_spawner(void *);
10034709573Sraf 
101f841f6adSraf /* Private interfaces elsewhere in libc */
102*7257d1b4Sraf extern int pthread_attr_clone(pthread_attr_t *, const pthread_attr_t *);
103*7257d1b4Sraf extern int pthread_attr_equal(const pthread_attr_t *, const pthread_attr_t *);
10434709573Sraf extern int _port_dispatch(int, int, int, int, uintptr_t, void *);
10534709573Sraf 
10634709573Sraf extern thread_communication_data_t *sigev_aio_tcd;
10734709573Sraf 
10834709573Sraf extern int timer_max;
10934709573Sraf extern thread_communication_data_t **timer_tcd;
11034709573Sraf 
11134709573Sraf #ifdef	__cplusplus
11234709573Sraf }
11334709573Sraf #endif
11434709573Sraf 
11534709573Sraf #endif	/* _SIGEV_THREAD_H */
116