1gensio_os_funcs(3) Library Functions Manual gensio_os_funcs(3)
2
3
4
6 gensio_os_funcs - Abstraction for some operating system functions used
7 by the gensio library
8
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
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
424 Return values are documented in the text above.
425
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)