Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
gensio_os_funcs(3)	   Library Functions Manual	    gensio_os_funcs(3)

NAME
       gensio_os_funcs	- Abstraction for some operating system	functions used
       by the gensio library

SYNOPSIS
       #include	<gensio/gensio_os_funcs_public.h>

       struct gensio_os_funcs {}

       int gensio_default_os_hnd(int wake_sig, struct gensio_os_funcs **o)

       int gensio_alloc_os_funcs(int wake_sig, struct gensio_os_funcs **o,
		       unsigned	int flags, ...)

       int gensio_unix_funcs_alloc(struct selector_s *sel, int wake_sig,
		 struct	gensio_os_funcs	**o)

       int gensio_win_funcs_alloc(struct gensio_os_funcs **o)

       void gensio_os_funcs_free(struct	gensio_os_funcs	*o);

       int gensio_os_proc_setup(struct gensio_os_funcs *o,
		       struct gensio_os_proc_data **data)

       void gensio_os_proc_cleanup(struct gensio_os_proc_data *data);

       int gensio_os_thread_setup(struct gensio_os_funcs *o);

       sigset_t	*gensio_os_proc_unix_get_wait_sigset(
				struct gensio_os_proc_data *data);

       int gensio_os_new_thread(struct gensio_os_funcs *o,
		       void (*start_func)(void *data), void *data,
		       struct gensio_thread **thread_id);

       int gensio_os_wait_thread(struct	gensio_thread *thread_id);

       int   gensio_os_proc_register_term_handler(struct   gensio_os_proc_data
       *data,
				 void (*handler)(void *handler_data),
				 void *handler_data);

       int  gensio_os_proc_register_reload_handler(struct  gensio_os_proc_data
       *data,
				   void	(*handler)(void	*handler_data),
				   void	*handler_data);

       int gensio_os_proc_register_winsize_handler(struct  gensio_os_proc_data
       *data,
				struct gensio_iod *console_iod,
				void (*handler)(int x_chrs, int	y_chrs,
					  int x_bits, int y_bits,
					  void *handler_data),
				void *handler_data);

       void *gensio_os_funcs_zalloc(struct gensio_os_funcs *o, gensiods	len);

       void gensio_os_funcs_zfree(struct gensio_os_funcs *o, void *data);

       struct  gensio_lock  *gensio_os_funcs_alloc_lock(struct gensio_os_funcs
       *o);

       void gensio_os_funcs_free_lock(struct gensio_os_funcs *o,
			     struct gensio_lock	*lock);

       void gensio_os_funcs_lock(struct	gensio_os_funcs	*o,
			struct gensio_lock *lock);

       void gensio_os_funcs_unlock(struct gensio_os_funcs *o,
			  struct gensio_lock *lock);

       void gensio_os_funcs_get_monotonic_time(struct gensio_os_funcs *o,
				gensio_time *time);

       struct gensio_timer *gensio_os_funcs_alloc_timer(struct gensio_os_funcs
       *o,
			       void (*handler)(struct gensio_timer *t,
					 void *cb_data),
			       void *cb_data);

       void gensio_os_funcs_free_timer(struct gensio_os_funcs *o,
			   struct gensio_timer *timer);

       int gensio_os_funcs_start_timer(struct gensio_os_funcs *o,
			   struct gensio_timer *timer,
			   gensio_time *timeout);

       int gensio_os_funcs_start_timer_abs(struct gensio_os_funcs *o,
			       struct gensio_timer *timer,
			       gensio_time *timeout);

       int gensio_os_funcs_stop_timer(struct gensio_os_funcs *o,
			     struct gensio_timer *timer);

       int gensio_os_funcs_stop_timer_with_done(struct gensio_os_funcs *o,
			  struct gensio_timer *timer,
			  void (*done_handler)(struct gensio_timer *t,
				      void *cb_data),
			  void *cb_data);

       struct	 gensio_runner	  *gensio_os_funcs_alloc_runner(struct	  gen-
       sio_os_funcs *o,
				 void (*handler)(struct	gensio_runner *r,
					   void	*cb_data),
				 void *cb_data);

       void gensio_os_funcs_free_runner(struct gensio_os_funcs *o,
			    struct gensio_runner *runner);

       int gensio_os_funcs_run(struct gensio_os_funcs *o,
		      struct gensio_runner *runner);

       typedef void (gensio_vlog_func)(struct gensio_os_funcs *o,
			   enum	gensio_log_levels level,
			   const char *log, va_list args);

       void gensio_os_funcs_set_vlog(struct gensio_os_funcs *o,
				     gensio_vlog_func func);

       int   gensio_os_funcs_service(struct  gensio_os_funcs  *o,  gensio_time
       *timeout);

       int gensio_os_funcs_handle_fork(struct gensio_os_funcs *o);

       struct	 gensio_waiter	  *gensio_os_funcs_alloc_waiter(struct	  gen-
       sio_os_funcs *o);

       void gensio_os_funcs_free_waiter(struct gensio_os_funcs *o,
			    struct gensio_waiter *waiter);

       int gensio_os_funcs_wait(struct gensio_os_funcs *o,
		       struct gensio_waiter *waiter, unsigned int count,
		       gensio_time *timeout);

       int gensio_os_funcs_wait_intr(struct gensio_os_funcs *o,
			    struct gensio_waiter *waiter, unsigned int count,
			    gensio_time	*timeout);

       int gensio_os_funcs_wait_intr_sigmask(struct gensio_os_funcs *o,
				 struct	gensio_waiter *waiter,
				 unsigned int count,
				 gensio_time *timeout,
				 struct	gensio_os_proc_data *proc_data);

       void gensio_os_funcs_wake(struct	gensio_os_funcs	*o,
			struct gensio_waiter *waiter);

       void gensio_os_funcs_set_data(struct gensio_os_funcs *o,	void *data);

       void *gensio_os_funcs_get_data(struct gensio_os_funcs *o);

DESCRIPTION
       This structure provides an abstraction for the gensio library that lets
       it  work	with various event libraries.  It provides the following basic
       functions:

       memory allocation - Allocate and	free memory.

       mutexes - Provide mutual	exclusion.

       file handler callbacks -	Allows file descriptors	to be monitored
	      and report when I/O is ready on them.

       timers -	Call callbacks after a certain amount of time has elapsed.

       runners - Run a function	in a new execution context.  Calling callbacks
	      straight from user functions can result in deadlocks, this  pro-
	      vides a way to call callbacks from a separate context.

       waiters - Wait for operations to	occur while running timers, runners
	      and watching for file descriptors.

       logging - Allow the gensio library to generate logs to report issues.

       This document describes the public functions that users can use.	 An os
       handler	has  many  other functions for use by gensios, these are docu-
       mented in the os	funcs include file.

       The basic issue is that there  are  various  event  handling  libraries
       (Tcl/Tk,	 glib,	Xlib, custom ones, etc.) and you may want to integrate
       the gensio library with one of these.  Even though it's a bit of	a pain
       to have to pass one of these around, it adds needed flexibility.

       gensio_default_os_hnd (Deprecated) provides a way to get	the default OS
       function	handler	for the	platform.  The same  value  will  be  returned
       each  time, only	one is created.	 You should generally use this one un-
       less you	have a special need as documented above.  Use of this  is  now
       discouraged in general.	Having two independent parts of	a system share
       an OS funcs without knowing about it is likely to lead to issues.  If a
       program	knows  it is the only thing using it, then this	is ok for now,
       but it's	going to be deprecated at some point.

       gensio_alloc_os_funcs allocates a new OS	function handler for the plat-
       form, for Unix or Windows.  Multiple OS handlers	can be used to	handle
       different  I/O  at different priorities.	 When you create a gensio, all
       I/O callbacks will be handled from the OS handler used  to  create  it.
       So  you	can run	different OS handlers in threads of different priority
       to run different	gensios	at different priority.	Otherwise there	is not
       much reason for more than one of	these.

       The wake_sig parameter usage on Windows is unused.  For	Unix  systems,
       this  signal is used to signal other processes that may be waiting that
       they need to wake up.  This is used to wake up a	process	waiting	 on  a
       waiter,	and  it's  used	 to signal all waiting processes if a timer is
       added that is sooner than any other timer  so  they  can	 adjust	 their
       waits.

       If you are running your program in a single thread, you can safely pass
       zero  into  this	 parameter.  If	you pass in anything but zero, it will
       set up that signal by removing it from the  sigmask  and	 installing  a
       handler for it.

       If  your	 app  is  multi-threaded (or, more accurately, if your app has
       multiple	threads	that are making	gensio calls) you must	pass  a	 valid
       signal into this, and you must set up an	empty handler for this signal,
       and  the	 signal	 must be blocked in all	threads	that call a wait func-
       tion.  You should not use this signal for anything else.	 The  function
       that  allocates	a  signal handler will block the signal	in the calling
       thread, and that	sigmask	is passed on to	other threads it creates.  But
       if you have allocated threads before allocating the os funcs, you  must
       make sure those other threads have this signal blocked.

       You  can	 pass in GENSIO_OS_FUNCS_DEFAULT_THREAD_SIGNAL to take the de-
       fault signal handler, which is SIGUSR1.

       On unix,	gensio_os_proc_setup function handles all the above  mentioned
       signal  setup  for  you (blocking signals, setting signal handler), for
       the wake	signal as above	and also for some other	signals	like  SIGTERM,
       SIGCHILD,  SIGPIPE,  and	 others.  You should generally use that	unless
       you have	special	needs.	It also	does neccessary	setup on Windows.

       Also, if	you pass in a different	value  to  gensio_default_os_hnd  than
       the  first one you passed in, it	will return GE_INVAL.  You can pass in
       different values	to gensio_unix_funcs_alloc  calls,  and	 it  will  use
       them,  but  there's  not	much value in this.  The os funcs for Unix can
       share a signal handler.	And there's not	 much  value  is  multiple  OS
       funcs, anyway.

       gensio_os_thread_setup  is  much	like gensio_os_proc_setup, but it only
       sets up the signal handlers and blocking	signals	for the	wakeup signal,
       it doesn't do any of the	other setup.  It allows	you to bring a	thread
       in  to  gensio that wasn't created by gensio.  It also does some	neces-
       sary setup on Windows for the thread.  If you have no  signal  handling
       needs,  you  can	 generally use this instead of gensio_os_proc_setup().
       If you  have  signal  handling  needs,  one  thread  should  call  gen-
       sio_os_proc_setup()  and	all other threads should call this function if
       they were not created by	gensio.

       gensio_unix_funcs_alloc and gensio_win_funcs_alloc allocate the	normal
       os funcs	for Unix and Windows based systems, respectively.

       The  sel	 parameter for Unix allows you to create your own selector ob-
       ject and	pass it	to the OS handler.  Passing in NULL will cause	it  to
       allocate	it's own selector object.  See the selector.h include file for
       details.

       The wake_sig value is a signal for use by the OS	functions for internal
       communication between threads.  If you are running a multi-threaded ap-
       plication,  you	must provide a valid signal that you don't use for any
       other  purpose,	generally  SIGUSR1  or	SIGUSR2.   You	can  use  GEN-
       SIO_DEF_WAKE_SIG	which is zero on Windows and SIGUSR1 on	Unix.

       The  gensio_os_proc_setup  function  does  all the standard setup for a
       process.	 You should almost certainly use this  function.   On  Windows
       this  sets  up  some basic things so termination	registering will work,
       but on Unix it does all the signal handling setup, so you don't have to
       do all the things mentioned above.  This	will  block  SIGPIPE  (because
       those  come  in when connections	die and	most applications don't	care),
       SIGCHLD (those come in for stdio	and pty	gensios), and the wake_sig  if
       that  is	 set.	It  also  install  signal handlers for SIGCHLD and the
       wake_sig	(if set) and sets up a signal mask.

       For Unix	this is	generally what you want, you don't want	SIGPIPE	 doing
       bad  things and having SIGCHLD wake up a	wait can speed things up a bit
       when waiting for	subprograms.

       If you use the gensio_os_funcs_wait_intr_sigmask	OS function, you  must
       pass  the  proc_data  value returned by gensio_os_proc_setup into that.
       If you  want  to	 modify	 the  wait  signal  mask,  you	can  use  gen-
       sio_os_proc_unix_get_wait_sigset	 to  fetch  a pointer to it and	modify
       it.

       Note that if  you  call	this  more  than  once	without	 calling  gen-
       sio_os_proc_cleanup inbetween, it will return GE_INUSE.

       The   gensio_os_proc_cleanup  function  undoes  all  the	 changes  gen-
       sio_os_proc_setup does, along with unregistering	 any  signal  handlers
       done by register	calls.	On Unix	it restores the	signal mask and	signal
       handlers	it sets	to their previous values.  On Windows it remove	regis-
       tered handlers.

       The  gensio_os_new_thread  function  starts  a new thread at start_func
       passing in the given data value.	 It returns a thread_id	that you  must
       pass  into  the wait function.  This is just basic generic threads, you
       can use your OS functions if you	need more control  over	 the  threads.
       If  you	use threads, make sure to see the notes	above about setting up
       for them	properly.  This	must be	called from a thread that  is  already
       set up.

       The  gensio_os_wait_thread  waits  for  a thread	to stop.  Note that it
       does not	cause the thread to stop, it waits for it to stop.   You  have
       to cause	the thread to stop yourself.

       The  gensio_os_proc_register_term_handler  function passes a handler to
       call when a termination (SIGINT,	SIGQUIT, SIGTERM on Unix, console con-
       trol handler or WM_CLOSE	on windows) is received	by the	process.   Set
       handler	to  NULL to disable.  If you do	this on	Unix, the signals will
       be blocked except when in a wait	or service  call.   Call  this	before
       starting	any other threads so they inherit the proper sigmask.

       The  gensio_os_proc_register_reload_handler  sets  the function to call
       when a reload is	requested by the operating system  (SIGHUP  on	Unix).
       Set  handler to NULL to disable.	 On Unix, this will cause SIGHUP to be
       blocked except when in a	wait or	service	call.  Call this before	start-
       ing any other threads so	they inherit the proper	sigmask.

       The gensio_os_proc_register_winsize_handler function sets the  function
       to call when a console window size change is requested by the operating
       system  (SIGWINCH  on  Unix, through the	console	interface on Windows).
       It will supply the new size parameters.	Set handler and	console_iod to
       NULL to disable.	 Note that the handler will  be	 called	 with  current
       window  size parameters after this is called.  This may be called after
       threads are started, the	SIGWINCH signal	mask is	set up by  default  in
       gensio_os_proc_setup on *nix systems.

       gensio_os_funcs_zalloc  allocates a block of memory and zeroes it.  The
       gensio library has it's own  allocator/deallocator  that	 is  using  in
       testing	to  track  if  all allocated data is freed when	the tests shut
       down, and to catch memory overruns, underruns, and use after  free  er-
       rors.   Returns	NULL  if  the  memory  cannot  be allocated.  Use gen-
       sio_os_funcs_zfree to free the allocated	memory.

       gensio_os_funcs_alloc_lock allocates a mutex that can be	used for lock-
       ing by the user.	 Use gensio_os_funcs_lock  and	gensio_os_funcs_unlock
       to lock/unlock the mutex.  The gensio_os_funcs_free_lock	will make sure
       the  lock  is  not  locked  and free the	data associated	with the lock.
       Note that even for os funcs that	don't implement	locks, this  will  im-
       plement a counter to make sure that all locks are balanced.

       gensio_os_funcs_get_monotonic_time returns a time value from the	monot-
       onic  clock used	for gensio_os_start_timer_abs.	It can also be used as
       a standard monotonic clock, but is not a	wall clock of any kind.

       gensio_os_funcs_set_vlog	must be	called by the user to set a  log  han-
       dling function for the os funcs.	 If something goes wrong internally in
       the  gensio library, this log function will be called to	report the is-
       sue.

       Timers are allocated with gensio_os_funcs_alloc_timer.  When the	 timer
       expires,	the handlers will be called with the given cb_data.  This will
       return  NULL  if	the timer cannot be allocated.	Timers are not running
       when allocated, the must	be started  with  gensio_os_funcs_start_timer,
       or  gensio_os_funcs_start_timer_abs.  The first starts a	timer relative
       to the current time.  The second	starts a timer based upon a  monotonic
       clock,  see gensio_os_funcs_get_monotonic_time for details.  These will
       return GE_INUSE if the timer was	already	running.   To  stop  a	timer,
       call	   either	gensio_os_funcs_stop_timer	 or	  gen-
       sio_os_funcs_stop_timer_with_done.  These both  return  GE_TIMEDOUT  if
       the  timer  is  not  running.   The first has no	way to assure that the
       timer is	finished running its handlers; the timer handler may still  be
       active  when  it	 returns.   If it does not return an error, the	second
       will call the  done_handler  function  when  the	 timer	is  completely
       stopped	and  all  the  handlers	are finished.  The second also returns
       GE_INUSE	if the timer has already been stopped  but  the	 done  handler
       hasn't been called yet.	Note that you cannot start the timer again un-
       til the done handler is called.	And finally, to	free a timer, use gen-
       sio_os_funcs_free_timer.	  The timer should not be running when calling
       this.

       Runners are sort	of like	zero-time timers, they will just be called im-
       mediately.  They	are useful for escaping	from deep  locking  situations
       where  you  want	 to  do	 something  at	the  base  context.   Use gen-
       sio_os_funcs_alloc_runner to allocate one of these.  It returns NULL if
       the runner cannot be allocated.	gensio_os_funcs_run causes the handler
       to be called.  It returns GE_INUSE if the runner	is  currently  already
       scheduled to be run.  And gensio_os_funcs_free_runner frees the runner.
       It should not be	currently scheduled to run.

       gensio_os_funcs_service	provides  the  main  service  function	to run
       timers, runners,	I/O handling, etc.  If it is interrupted by  a	signal
       (on  Unix), it returns GE_INTERRUPTED.  If timeout is non-NULL, it is a
       relative	amount of time to wait and this	will return GE_TIMEDOUT	if the
       timeout expires.	 Note that for long timeouts (days)  this  may	return
       early  on  some	os funcs, so don't rely	on this	for timing.  When this
       returns,	the timeout will be updated to any remaining time, even	on  an
       early  timeout.	Generally you don't use	this function, you use waiters
       instead.

       Call gensio_os_funcs_handle_fork	in the child  function	after  a  fork
       (Unix  only).  This cleans up various things and	readies	the gensio li-
       brary to	be used	after a	fork.  If this returns an error, it is	likely
       that the	gensio library is unusable on the child.

       Waiters	are used to wait for things to happen.	When the thing happens
       occurs, that code should	call wake to wake the waiter.  Normal  servic-
       ing  of	tiers, runners,	I/O, etc. are done while waiting.  Waiters and
       wakes are count based, if you call the wake before the wait that's  ok,
       the  wake  will	be  waiting when the wait happens.  If you call	wake 3
       times, there are	3 wakes	pending.  To  allocate	a  waiter,  call  gen-
       sio_os_funcs_alloc_waiter.   It	returns	NULL if	it cannot allocate the
       waiter.	gensio_os_funcs_wait waits for count wakeups to	 be  done  and
       then  returns zero.  If timeout is NULL it waits	forever.  Otherwise if
       the timeout expires it returns GE_TIMEDOUT and the timeout  is  updated
       to the remaining	time.  If this times out, no wakeups are "used"	by the
       function,  if  only  some  are  pending	those are still	pending.  gen-
       sio_os_funcs_wait_intr is like gensio_os_funcs_wait except if an	signal
       is  received  (Unix  only)  it  will   return   GE_INTERRUPTED.	  gen-
       sio_os_funcs_wait_intr_sigmask  is  like	 gensio_os_funcs_wait_intr but
       allows a	user-specified signal mask to be installed (Unix  only).   See
       gensio_os_proc_setup for	details.  To send a single wakeup to a waiter,
       use     gensio_os_funcs_wake.	 And,	 of    course,	  call	  gen-
       sio_os_funcs_free_waiter	to free	a waiter.

       An os funcs has a single	void pointer that the user  may	 install  some
       data  in	 for  their own	use.  Use gensio_os_funcs_set_data to set this
       data and	gensio_os_funcs_get_data to retrieve it.

RETURN VALUES
       Return values are documented in the text	above.

SEE ALSO
       gensio_set_log_mask(3),		gensio_get_log_mask(3),		  gen-
       sio_log_level_to_str(3),	gensio(5), gensio_err(3)

				  23 Feb 2019		    gensio_os_funcs(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=gensio_unix_funcs_alloc&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help