1gensio_os_funcs(3)         Library Functions Manual         gensio_os_funcs(3)
2
3
4

NAME

6       gensio_os_funcs  - Abstraction for some operating system functions used
7       by the gensio library
8

SYNOPSIS

10       #include <gensio/gensio_os_funcs_public.h>
11
12       struct gensio_os_funcs {}
13
14       int gensio_default_os_hnd(int wake_sig, struct gensio_os_funcs **o)
15
16       int gensio_alloc_os_funcs(int wake_sig, struct gensio_os_funcs **o,
17                       unsigned int flags, ...)
18
19       int gensio_unix_funcs_alloc(struct selector_s *sel, int wake_sig,
20                 struct gensio_os_funcs **o)
21
22       int gensio_win_funcs_alloc(struct gensio_os_funcs **o)
23
24       void gensio_os_funcs_free(struct gensio_os_funcs *o);
25
26       int gensio_os_proc_setup(struct gensio_os_funcs *o,
27                       struct gensio_os_proc_data **data)
28
29       void gensio_os_proc_cleanup(struct gensio_os_proc_data *data);
30
31       int gensio_os_thread_setup(struct gensio_os_funcs *o);
32
33       sigset_t *gensio_os_proc_unix_get_wait_sigset(
34                                struct gensio_os_proc_data *data);
35
36       int gensio_os_new_thread(struct gensio_os_funcs *o,
37                       void (*start_func)(void *data), void *data,
38                       struct gensio_thread **thread_id);
39
40       int gensio_os_wait_thread(struct gensio_thread *thread_id);
41
42       int   gensio_os_proc_register_term_handler(struct   gensio_os_proc_data
43       *data,
44                                 void (*handler)(void *handler_data),
45                                 void *handler_data);
46
47       int  gensio_os_proc_register_reload_handler(struct  gensio_os_proc_data
48       *data,
49                                   void (*handler)(void *handler_data),
50                                   void *handler_data);
51
52       int gensio_os_proc_register_winsize_handler(struct  gensio_os_proc_data
53       *data,
54                                struct gensio_iod *console_iod,
55                                void (*handler)(int x_chrs, int y_chrs,
56                                          int x_bits, int y_bits,
57                                          void *handler_data),
58                                void *handler_data);
59
60       void *gensio_os_funcs_zalloc(struct gensio_os_funcs *o, gensiods len);
61
62       void gensio_os_funcs_zfree(struct gensio_os_funcs *o, void *data);
63
64       struct  gensio_lock  *gensio_os_funcs_alloc_lock(struct gensio_os_funcs
65       *o);
66
67       void gensio_os_funcs_free_lock(struct gensio_os_funcs *o,
68                             struct gensio_lock *lock);
69
70       void gensio_os_funcs_lock(struct gensio_os_funcs *o,
71                        struct gensio_lock *lock);
72
73       void gensio_os_funcs_unlock(struct gensio_os_funcs *o,
74                          struct gensio_lock *lock);
75
76       void gensio_os_funcs_get_monotonic_time(struct gensio_os_funcs *o,
77                                gensio_time *time);
78
79       struct gensio_timer *gensio_os_funcs_alloc_timer(struct gensio_os_funcs
80       *o,
81                               void (*handler)(struct gensio_timer *t,
82                                         void *cb_data),
83                               void *cb_data);
84
85       void gensio_os_funcs_free_timer(struct gensio_os_funcs *o,
86                           struct gensio_timer *timer);
87
88       int gensio_os_funcs_start_timer(struct gensio_os_funcs *o,
89                           struct gensio_timer *timer,
90                           gensio_time *timeout);
91
92       int gensio_os_funcs_start_timer_abs(struct gensio_os_funcs *o,
93                               struct gensio_timer *timer,
94                               gensio_time *timeout);
95
96       int gensio_os_funcs_stop_timer(struct gensio_os_funcs *o,
97                             struct gensio_timer *timer);
98
99       int gensio_os_funcs_stop_timer_with_done(struct gensio_os_funcs *o,
100                          struct gensio_timer *timer,
101                          void (*done_handler)(struct gensio_timer *t,
102                                      void *cb_data),
103                          void *cb_data);
104
105       struct    gensio_runner    *gensio_os_funcs_alloc_runner(struct    gen‐
106       sio_os_funcs *o,
107                                 void (*handler)(struct gensio_runner *r,
108                                           void *cb_data),
109                                 void *cb_data);
110
111       void gensio_os_funcs_free_runner(struct gensio_os_funcs *o,
112                            struct gensio_runner *runner);
113
114       int gensio_os_funcs_run(struct gensio_os_funcs *o,
115                      struct gensio_runner *runner);
116
117       typedef void (gensio_vlog_func)(struct gensio_os_funcs *o,
118                           enum gensio_log_levels level,
119                           const char *log, va_list args);
120
121       void gensio_os_funcs_set_vlog(struct gensio_os_funcs *o,
122                                     gensio_vlog_func func);
123
124       int  gensio_os_funcs_service(struct  gensio_os_funcs  *o,   gensio_time
125       *timeout);
126
127       int gensio_os_funcs_handle_fork(struct gensio_os_funcs *o);
128
129       struct    gensio_waiter    *gensio_os_funcs_alloc_waiter(struct    gen‐
130       sio_os_funcs *o);
131
132       void gensio_os_funcs_free_waiter(struct gensio_os_funcs *o,
133                            struct gensio_waiter *waiter);
134
135       int gensio_os_funcs_wait(struct gensio_os_funcs *o,
136                       struct gensio_waiter *waiter, unsigned int count,
137                       gensio_time *timeout);
138
139       int gensio_os_funcs_wait_intr(struct gensio_os_funcs *o,
140                            struct gensio_waiter *waiter, unsigned int count,
141                            gensio_time *timeout);
142
143       int gensio_os_funcs_wait_intr_sigmask(struct gensio_os_funcs *o,
144                                 struct gensio_waiter *waiter,
145                                 unsigned int count,
146                                 gensio_time *timeout,
147                                 struct gensio_os_proc_data *proc_data);
148
149       void gensio_os_funcs_wake(struct gensio_os_funcs *o,
150                        struct gensio_waiter *waiter);
151
152       void gensio_os_funcs_set_data(struct gensio_os_funcs *o, void *data);
153
154       void *gensio_os_funcs_get_data(struct gensio_os_funcs *o);
155

DESCRIPTION

157       This structure provides an abstraction for the gensio library that lets
158       it  work with various event libraries.  It provides the following basic
159       functions:
160
161       memory allocation - Allocate and free memory.
162
163       mutexes - Provide mutual exclusion.
164
165       file handler callbacks - Allows file descriptors to be monitored
166              and report when I/O is ready on them.
167
168       timers - Call callbacks after a certain amount of time has elapsed.
169
170       runners - Run a function in a new execution context.  Calling callbacks
171              straight from user functions can result in deadlocks, this  pro‐
172              vides a way to call callbacks from a separate context.
173
174       waiters - Wait for operations to occur while running timers, runners
175              and watching for file descriptors.
176
177       logging - Allow the gensio library to generate logs to report issues.
178
179       This document describes the public functions that users can use.  An os
180       handler has many other functions for use by gensios,  these  are  docu‐
181       mented in the os funcs include file.
182
183       The  basic  issue  is  that  there are various event handling libraries
184       (Tcl/Tk, glib, Xlib, custom ones, etc.) and you may want  to  integrate
185       the gensio library with one of these.  Even though it's a bit of a pain
186       to have to pass one of these around, it adds needed flexibility.
187
188       gensio_default_os_hnd (Deprecated) provides a way to get the default OS
189       function  handler  for  the  platform.  The same value will be returned
190       each time, only one is created.  You should generally use this one  un‐
191       less  you  have a special need as documented above.  Use of this is now
192       discouraged in general.  Having two independent parts of a system share
193       an OS funcs without knowing about it is likely to lead to issues.  If a
194       program knows it is the only thing using it, then this is ok  for  now,
195       but it's going to be deprecated at some point.
196
197       gensio_alloc_os_funcs allocates a new OS function handler for the plat‐
198       form, for Unix or Windows.  Multiple OS handlers can be used to  handle
199       different  I/O  at different priorities.  When you create a gensio, all
200       I/O callbacks will be handled from the OS handler used  to  create  it.
201       So  you  can run different OS handlers in threads of different priority
202       to run different gensios at different priority.  Otherwise there is not
203       much reason for more than one of these.
204
205       The  wake_sig  parameter usage on Windows is unused.  For Unix systems,
206       this signal is used to signal other processes that may be waiting  that
207       they  need  to wake up.  This is used to wake up a process waiting on a
208       waiter, and it's used to signal all waiting processes  if  a  timer  is
209       added  that  is  sooner  than  any other timer so they can adjust their
210       waits.
211
212       If you are running your program in a single thread, you can safely pass
213       zero  into  this  parameter.  If you pass in anything but zero, it will
214       set up that signal by removing it from the  sigmask  and  installing  a
215       handler for it.
216
217       If  your  app  is  multi-threaded (or, more accurately, if your app has
218       multiple threads that are making gensio calls) you must  pass  a  valid
219       signal into this, and you must set up an empty handler for this signal,
220       and the signal must be blocked in all threads that call  a  wait  func‐
221       tion.   You should not use this signal for anything else.  The function
222       that allocates a signal handler will block the signal  in  the  calling
223       thread, and that sigmask is passed on to other threads it creates.  But
224       if you have allocated threads before allocating the os funcs, you  must
225       make sure those other threads have this signal blocked.
226
227       You  can  pass in GENSIO_OS_FUNCS_DEFAULT_THREAD_SIGNAL to take the de‐
228       fault signal handler, which is SIGUSR1.
229
230       On unix, gensio_os_proc_setup function handles all the above  mentioned
231       signal  setup  for  you (blocking signals, setting signal handler), for
232       the wake signal as above and also for some other signals like  SIGTERM,
233       SIGCHILD,  SIGPIPE,  and  others.  You should generally use that unless
234       you have special needs.  It also does neccessary setup on Windows.
235
236       Also, if you pass in a different value  to  gensio_default_os_hnd  than
237       the  first one you passed in, it will return GE_INVAL.  You can pass in
238       different values to gensio_unix_funcs_alloc  calls,  and  it  will  use
239       them,  but  there's  not much value in this.  The os funcs for Unix can
240       share a signal handler.  And there's not  much  value  is  multiple  OS
241       funcs, anyway.
242
243       gensio_os_thread_setup  is  much like gensio_os_proc_setup, but it only
244       sets up the signal handlers and blocking signals for the wakeup signal,
245       it  doesn't do any of the other setup.  It allows you to bring a thread
246       in to gensio that wasn't created by gensio.  It also does  some  neces‐
247       sary  setup  on Windows for the thread.  If you have no signal handling
248       needs, you can generally use this  instead  of  gensio_os_proc_setup().
249       If  you  have  signal  handling  needs,  one  thread  should  call gen‐
250       sio_os_proc_setup() and all other threads should call this function  if
251       they were not created by gensio.
252
253       gensio_unix_funcs_alloc  and gensio_win_funcs_alloc allocate the normal
254       os funcs for Unix and Windows based systems, respectively.
255
256       The sel parameter for Unix allows you to create your own  selector  ob‐
257       ject  and  pass it to the OS handler.  Passing in NULL will cause it to
258       allocate it's own selector object.  See the selector.h include file for
259       details.
260
261       The wake_sig value is a signal for use by the OS functions for internal
262       communication between threads.  If you are running a multi-threaded ap‐
263       plication,  you  must provide a valid signal that you don't use for any
264       other  purpose,  generally  SIGUSR1  or  SIGUSR2.   You  can  use  GEN‐
265       SIO_DEF_WAKE_SIG which is zero on Windows and SIGUSR1 on Unix.
266
267       The  gensio_os_proc_setup  function  does  all the standard setup for a
268       process.  You should almost certainly use this  function.   On  Windows
269       this  sets  up  some basic things so termination registering will work,
270       but on Unix it does all the signal handling setup, so you don't have to
271       do  all  the  things mentioned above.  This will block SIGPIPE (because
272       those come in when connections die and most applications  don't  care),
273       SIGCHLD  (those come in for stdio and pty gensios), and the wake_sig if
274       that is set.  It also install  signal  handlers  for  SIGCHLD  and  the
275       wake_sig (if set) and sets up a signal mask.
276
277       For  Unix this is generally what you want, you don't want SIGPIPE doing
278       bad things and having SIGCHLD wake up a wait can speed things up a  bit
279       when waiting for subprograms.
280
281       If  you use the gensio_os_funcs_wait_intr_sigmask OS function, you must
282       pass the proc_data value returned by  gensio_os_proc_setup  into  that.
283       If  you  want  to  modify  the  wait  signal  mask,  you  can  use gen‐
284       sio_os_proc_unix_get_wait_sigset to fetch a pointer to  it  and  modify
285       it.
286
287       Note  that  if  you  call  this  more  than  once  without calling gen‐
288       sio_os_proc_cleanup inbetween, it will return GE_INUSE.
289
290       The  gensio_os_proc_cleanup  function  undoes  all  the  changes   gen‐
291       sio_os_proc_setup  does,  along  with unregistering any signal handlers
292       done by register calls.  On Unix it restores the signal mask and signal
293       handlers it sets to their previous values.  On Windows it remove regis‐
294       tered handlers.
295
296       The gensio_os_new_thread function starts a  new  thread  at  start_func
297       passing  in the given data value.  It returns a thread_id that you must
298       pass into the wait function.  This is just basic generic  threads,  you
299       can  use  your  OS functions if you need more control over the threads.
300       If you use threads, make sure to see the notes above about  setting  up
301       for  them  properly.  This must be called from a thread that is already
302       set up.
303
304       The gensio_os_wait_thread waits for a thread to  stop.   Note  that  it
305       does  not  cause the thread to stop, it waits for it to stop.  You have
306       to cause the thread to stop yourself.
307
308       The gensio_os_proc_register_term_handler function passes a  handler  to
309       call when a termination (SIGINT, SIGQUIT, SIGTERM on Unix, console con‐
310       trol handler or WM_CLOSE on windows) is received by the  process.   Set
311       handler  to  NULL to disable.  If you do this on Unix, the signals will
312       be blocked except when in a wait or service  call.   Call  this  before
313       starting any other threads so they inherit the proper sigmask.
314
315       The  gensio_os_proc_register_reload_handler  sets  the function to call
316       when a reload is requested by the operating system  (SIGHUP  on  Unix).
317       Set  handler to NULL to disable.  On Unix, this will cause SIGHUP to be
318       blocked except when in a wait or service call.  Call this before start‐
319       ing any other threads so they inherit the proper sigmask.
320
321       The  gensio_os_proc_register_winsize_handler function sets the function
322       to call when a console window size change is requested by the operating
323       system  (SIGWINCH  on  Unix, through the console interface on Windows).
324       It will supply the new size parameters.  Set handler and console_iod to
325       NULL  to  disable.   Note  that the handler will be called with current
326       window size parameters after this is called.  This may be called  after
327       threads  are  started, the SIGWINCH signal mask is set up by default in
328       gensio_os_proc_setup on *nix systems.
329
330       gensio_os_funcs_zalloc allocates a block of memory and zeroes it.   The
331       gensio  library  has  it's  own  allocator/deallocator that is using in
332       testing to track if all allocated data is freed  when  the  tests  shut
333       down,  and  to catch memory overruns, underruns, and use after free er‐
334       rors.  Returns NULL if  the  memory  cannot  be  allocated.   Use  gen‐
335       sio_os_funcs_zfree to free the allocated memory.
336
337       gensio_os_funcs_alloc_lock allocates a mutex that can be used for lock‐
338       ing by the user.  Use gensio_os_funcs_lock  and  gensio_os_funcs_unlock
339       to lock/unlock the mutex.  The gensio_os_funcs_free_lock will make sure
340       the lock is not locked and free the  data  associated  with  the  lock.
341       Note  that  even for os funcs that don't implement locks, this will im‐
342       plement a counter to make sure that all locks are balanced.
343
344       gensio_os_funcs_get_monotonic_time returns a time value from the  mono‐
345       tonic clock used for gensio_os_start_timer_abs.  It can also be used as
346       a standard monotonic clock, but is not a wall clock of any kind.
347
348       gensio_os_funcs_set_vlog must be called by the user to set a  log  han‐
349       dling function for the os funcs.  If something goes wrong internally in
350       the gensio library, this log function will be called to report the  is‐
351       sue.
352
353       Timers  are allocated with gensio_os_funcs_alloc_timer.  When the timer
354       expires, the handlers will be called with the given cb_data.  This will
355       return  NULL  if the timer cannot be allocated.  Timers are not running
356       when allocated, the must be started  with  gensio_os_funcs_start_timer,
357       or  gensio_os_funcs_start_timer_abs.  The first starts a timer relative
358       to the current time.  The second starts a timer based upon a  monotonic
359       clock,  see gensio_os_funcs_get_monotonic_time for details.  These will
360       return GE_INUSE if the timer was already running.   To  stop  a  timer,
361       call        either       gensio_os_funcs_stop_timer       or       gen‐
362       sio_os_funcs_stop_timer_with_done.  These both  return  GE_TIMEDOUT  if
363       the  timer  is  not  running.   The first has no way to assure that the
364       timer is finished running its handlers; the timer handler may still  be
365       active  when  it  returns.   If it does not return an error, the second
366       will call the  done_handler  function  when  the  timer  is  completely
367       stopped  and  all  the  handlers are finished.  The second also returns
368       GE_INUSE if the timer has already been stopped  but  the  done  handler
369       hasn't been called yet.  Note that you cannot start the timer again un‐
370       til the done handler is called.  And finally, to free a timer, use gen‐
371       sio_os_funcs_free_timer.   The timer should not be running when calling
372       this.
373
374       Runners are sort of like zero-time timers, they will just be called im‐
375       mediately.   They  are useful for escaping from deep locking situations
376       where you  want  to  do  something  at  the  base  context.   Use  gen‐
377       sio_os_funcs_alloc_runner to allocate one of these.  It returns NULL if
378       the runner cannot be allocated.  gensio_os_funcs_run causes the handler
379       to  be  called.  It returns GE_INUSE if the runner is currently already
380       scheduled to be run.  And gensio_os_funcs_free_runner frees the runner.
381       It should not be currently scheduled to run.
382
383       gensio_os_funcs_service  provides  the  main  service  function  to run
384       timers, runners, I/O handling, etc.  If it is interrupted by  a  signal
385       (on  Unix), it returns GE_INTERRUPTED.  If timeout is non-NULL, it is a
386       relative amount of time to wait and this will return GE_TIMEDOUT if the
387       timeout  expires.   Note  that for long timeouts (days) this may return
388       early on some os funcs, so don't rely on this for  timing.   When  this
389       returns,  the timeout will be updated to any remaining time, even on an
390       early timeout.  Generally you don't use this function, you use  waiters
391       instead.
392
393       Call  gensio_os_funcs_handle_fork  in  the  child function after a fork
394       (Unix only).  This cleans up various things and readies the gensio  li‐
395       brary  to be used after a fork.  If this returns an error, it is likely
396       that the gensio library is unusable on the child.
397
398       Waiters are used to wait for things to happen.  When the thing  happens
399       occurs,  that code should call wake to wake the waiter.  Normal servic‐
400       ing of tiers, runners, I/O, etc. are done while waiting.   Waiters  and
401       wakes  are count based, if you call the wake before the wait that's ok,
402       the wake will be waiting when the wait happens.  If  you  call  wake  3
403       times,  there  are  3  wakes  pending.  To allocate a waiter, call gen‐
404       sio_os_funcs_alloc_waiter.  It returns NULL if it cannot  allocate  the
405       waiter.   gensio_os_funcs_wait  waits  for count wakeups to be done and
406       then returns zero.  If timeout is NULL it waits forever.  Otherwise  if
407       the  timeout  expires it returns GE_TIMEDOUT and the timeout is updated
408       to the remaining time.  If this times out, no wakeups are "used" by the
409       function,  if  only  some  are  pending  those are still pending.  gen‐
410       sio_os_funcs_wait_intr is like gensio_os_funcs_wait except if an signal
411       is   received   (Unix   only)  it  will  return  GE_INTERRUPTED.   gen‐
412       sio_os_funcs_wait_intr_sigmask is  like  gensio_os_funcs_wait_intr  but
413       allows  a  user-specified signal mask to be installed (Unix only).  See
414       gensio_os_proc_setup for details.  To send a single wakeup to a waiter,
415       use     gensio_os_funcs_wake.     And,    of    course,    call    gen‐
416       sio_os_funcs_free_waiter to free a waiter.
417
418       An os funcs has a single void pointer that the user  may  install  some
419       data  in  for  their own use.  Use gensio_os_funcs_set_data to set this
420       data and gensio_os_funcs_get_data to retrieve it.
421
422

RETURN VALUES

424       Return values are documented in the text above.
425

SEE ALSO

427       gensio_set_log_mask(3),          gensio_get_log_mask(3),           gen‐
428       sio_log_level_to_str(3), gensio(5), gensio_err(3)
429
430
431
432                                  23 Feb 2019               gensio_os_funcs(3)
Impressum