su 1.12.10
|
00001 /* 00002 * This file is part of the Sofia-SIP package 00003 * 00004 * Copyright (C) 2005 Nokia Corporation. 00005 * 00006 * Contact: Pekka Pessi <pekka.pessi@nokia-email.address.hidden> 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00021 * 02110-1301 USA 00022 * 00023 */ 00024 00025 #ifndef SU_WAIT_H 00026 00027 #define SU_WAIT_H 00028 00038 /* ---------------------------------------------------------------------- */ 00039 /* Includes */ 00040 00041 #ifndef SU_H 00042 #include "sofia-sip/su.h" 00043 #endif 00044 00045 #ifndef SU_TIME_H 00046 #include "sofia-sip/su_time.h" 00047 #endif 00048 00049 #if SU_HAVE_POLL 00050 #include <sys/poll.h> 00051 #endif 00052 00053 SOFIA_BEGIN_DECLS 00054 00055 /* ---------------------------------------------------------------------- */ 00056 /* Constants */ 00057 00058 #if SU_HAVE_KQUEUE 00059 00060 #define SU_WAIT_CMP(x, y) \ 00061 (((x).ident - (y).ident) ? ((x).ident - (y).ident) : ((x).flags - (y).flags)) 00062 00064 #define SU_WAIT_IN (EVFILT_READ) 00065 00066 #define SU_WAIT_OUT (EVFILT_WRITE) 00067 00068 #define SU_WAIT_CONNECT (EVFILT_WRITE) 00069 00070 #define SU_WAIT_ERR (EV_ERROR) 00071 00072 #define SU_WAIT_HUP (EV_EOF) 00073 00074 #define SU_WAIT_ACCEPT (EVFILT_READ) 00075 00077 #define SU_WAIT_FOREVER (-1) 00078 00079 #define SU_WAIT_TIMEOUT (-2) 00080 00082 #define SU_WAIT_INIT { INVALID_SOCKET, 0, 0, 0, 0, NULL } 00083 00085 #define SU_WAIT_MAX (0x7fffffff) 00086 00087 #elif SU_HAVE_POLL || DOCUMENTATION_ONLY 00088 00089 #define SU_WAIT_CMP(x, y) \ 00090 (((x).fd - (y).fd) ? ((x).fd - (y).fd) : ((x).events - (y).events)) 00091 00093 #define SU_WAIT_IN (POLLIN) 00094 00095 #define SU_WAIT_OUT (POLLOUT) 00096 00097 #define SU_WAIT_CONNECT (POLLOUT) 00098 00099 #define SU_WAIT_ERR (POLLERR) 00100 00101 #define SU_WAIT_HUP (POLLHUP) 00102 00103 #define SU_WAIT_ACCEPT (POLLIN) 00104 00106 #define SU_WAIT_FOREVER (-1) 00107 00108 #define SU_WAIT_TIMEOUT (-2) 00109 00111 #define SU_WAIT_INIT { INVALID_SOCKET, 0, 0 } 00112 00114 #define SU_WAIT_MAX (0x7fffffff) 00115 00116 #elif SU_HAVE_WINSOCK 00117 00118 #define SU_WAIT_CMP(x, y) ((intptr_t)(x) - (intptr_t)(y)) 00119 00120 #define SU_WAIT_IN (FD_READ) 00121 #define SU_WAIT_OUT (FD_WRITE) 00122 #define SU_WAIT_CONNECT (FD_CONNECT) 00123 #define SU_WAIT_ERR (0) /* let's get it on */ 00124 #define SU_WAIT_HUP (FD_CLOSE) 00125 #define SU_WAIT_ACCEPT (FD_ACCEPT) 00126 00127 #define SU_WAIT_FOREVER (WSA_INFINITE) 00128 #define SU_WAIT_TIMEOUT (WSA_WAIT_TIMEOUT) 00129 00130 #define SU_WAIT_INIT NULL 00131 00132 #define SU_WAIT_MAX (64) 00133 00134 #else 00135 /* If nothing works, try these */ 00136 00137 #define POLLIN 0x001 00138 #define POLLPRI 0x002 00139 #define POLLOUT 0x004 00140 00141 #ifdef __USE_XOPEN 00142 #define POLLRDNORM 0x040 00143 #define POLLRDBAND 0x080 00144 #define POLLWRNORM 0x100 00145 #define POLLWRBAND 0x200 00146 #endif 00147 00148 /* These for pollfd.revents */ 00149 #define POLLERR 0x008 00150 #define POLLHUP 0x010 00151 #define POLLNVAL 0x020 00152 00153 #define SU_WAIT_CMP(x, y) \ 00154 (((x).fd - (y).fd) ? ((x).fd - (y).fd) : ((x).events - (y).events)) 00155 00156 #define SU_WAIT_IN POLLIN 00157 #define SU_WAIT_OUT POLLOUT 00158 #define SU_WAIT_CONNECT POLLOUT 00159 #define SU_WAIT_ERR POLLERR 00160 #define SU_WAIT_HUP POLLHUP 00161 #define SU_WAIT_ACCEPT POLLIN 00162 #define SU_WAIT_FOREVER (-1) 00163 #define SU_WAIT_TIMEOUT (-2) 00164 00165 #define SU_WAIT_INIT { INVALID_SOCKET, 0, 0 } 00166 00168 #define SU_WAIT_MAX (0x7fffffff) 00169 00170 #endif 00171 00172 /* ---------------------------------------------------------------------- */ 00173 /* Types */ 00174 00176 #if SU_HAVE_KQUEUE 00177 typedef struct kevent su_wait_t; 00178 #elif SU_HAVE_POLL 00179 typedef struct pollfd su_wait_t; 00180 #elif SU_HAVE_WINSOCK 00181 typedef HANDLE su_wait_t; 00182 #else 00183 /* typedef struct os_specific su_wait_t; */ 00184 typedef struct pollfd su_wait_t; 00185 struct pollfd { 00186 su_socket_t fd; /* file descriptor */ 00187 short events; /* requested events */ 00188 short revents; /* returned events */ 00189 }; 00190 00191 00192 /* Type used for the number of file descriptors. */ 00193 typedef unsigned long int nfds_t; 00194 00195 /* Poll the file descriptors described by the NFDS structures starting at 00196 FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for 00197 an event to occur; if TIMEOUT is -1, block until an event occurs. 00198 Returns the number of file descriptors with events, zero if timed out, 00199 or -1 for errors. */ 00200 int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout); 00201 00202 #endif 00203 00204 /* Used by AD */ 00205 typedef int su_success_t; 00206 00207 /* ---------------------------------------------------------------------- */ 00208 00210 typedef struct su_root_s su_root_t; 00211 00212 #ifndef SU_ROOT_MAGIC_T 00213 00223 #define SU_ROOT_MAGIC_T void 00224 #endif 00225 00236 typedef SU_ROOT_MAGIC_T su_root_magic_t; 00237 00238 #ifndef SU_WAKEUP_ARG_T 00239 00249 #define SU_WAKEUP_ARG_T void 00250 #endif 00251 00261 typedef SU_WAKEUP_ARG_T su_wakeup_arg_t; 00262 00268 typedef int (*su_wakeup_f)(su_root_magic_t *, 00269 su_wait_t *, 00270 su_wakeup_arg_t *arg); 00271 00272 enum { 00273 su_pri_normal, 00274 su_pri_first, 00275 su_pri_realtime 00276 }; 00277 00278 struct _GSource; 00279 00281 SOFIAPUBVAR int su_root_size_hint; 00282 00283 /* ---------------------------------------------------------------------- */ 00284 /* Pre-poll callback */ 00285 00286 #ifndef SU_PREPOLL_MAGIC_T 00287 00297 #define SU_PREPOLL_MAGIC_T void 00298 #endif 00299 00310 typedef SU_PREPOLL_MAGIC_T su_prepoll_magic_t; 00311 00312 00317 typedef void su_prepoll_f(su_prepoll_magic_t *, su_root_t *); 00318 00319 /* ---------------------------------------------------------------------- */ 00320 00321 /* Timers */ 00322 #ifdef SU_TIMER_T 00323 #error SU_TIMER_T defined 00324 #endif 00325 00326 #ifndef SU_TIMER_ARG_T 00327 00330 #define SU_TIMER_ARG_T void 00331 #endif 00332 00334 typedef struct su_timer_s su_timer_t; 00335 00337 typedef SU_TIMER_ARG_T su_timer_arg_t; 00338 00340 typedef void (*su_timer_f)(su_root_magic_t *magic, 00341 su_timer_t *t, 00342 su_timer_arg_t *arg); 00343 00344 #ifndef SU_TIMER_QUEUE_T 00345 #define SU_TIMER_QUEUE_T su_timer_t * 00346 #endif 00347 00348 typedef SU_TIMER_QUEUE_T su_timer_queue_t; 00349 00350 /* ---------------------------------------------------------------------- */ 00351 00352 /* Tasks */ 00353 00355 typedef struct su_port_s su_port_t; 00356 00357 typedef struct { su_port_t *sut_port; su_root_t *sut_root; } _su_task_t; 00358 00360 typedef _su_task_t su_task_r[1]; 00361 00363 #define SU_TASK_R_INIT {{ NULL, NULL }} 00364 00365 /* This must be used instead of su_task_r as return value type. */ 00366 typedef _su_task_t const *_su_task_r; 00367 00368 /* ---------------------------------------------------------------------- */ 00369 00370 /* Messages */ 00371 #ifndef SU_MSG_ARG_T 00372 00375 #define SU_MSG_ARG_T void 00376 #endif 00377 00379 typedef SU_MSG_ARG_T su_msg_arg_t; 00380 00382 typedef struct su_msg_s su_msg_t; 00383 00385 typedef su_msg_t *su_msg_r[1]; 00386 00391 typedef su_msg_t * const su_msg_cr[1]; 00392 00394 #define SU_MSG_R_INIT { NULL } 00395 00397 typedef void su_msg_function(su_root_magic_t *magic, 00398 su_msg_r msg, 00399 su_msg_arg_t *arg); 00400 00402 typedef void su_msg_deinit_function(su_msg_arg_t *arg); 00403 00405 typedef su_msg_function *su_msg_f; 00406 00407 00408 /* ---------------------------------------------------------------------- */ 00409 00410 /* Clones */ 00411 #ifndef SU_CLONE_T 00412 #define SU_CLONE_T struct su_clone_s 00413 #endif 00414 00416 typedef SU_CLONE_T *su_clone_r[1]; 00417 00419 #define SU_CLONE_R_INIT {NULL} 00420 00422 typedef int (*su_root_init_f)(su_root_t *, su_root_magic_t *); 00423 00425 typedef void (*su_root_deinit_f)(su_root_t *, su_root_magic_t *); 00426 00427 /* ---------------------------------------------------------------------- */ 00428 /* Functions */ 00429 00430 /* Wait */ 00431 SOFIAPUBFUN void su_wait_init(su_wait_t dst[1]); 00432 SOFIAPUBFUN int su_wait_create(su_wait_t *dst, su_socket_t s, int events); 00433 SOFIAPUBFUN int su_wait_destroy(su_wait_t *dst); 00434 SOFIAPUBFUN int su_wait(su_wait_t waits[], unsigned n, su_duration_t timeout); 00435 SOFIAPUBFUN int su_wait_events(su_wait_t *wait, su_socket_t s); 00436 SOFIAPUBFUN int su_wait_mask(su_wait_t *dst, su_socket_t s, int events); 00437 00438 #if !HAVE_WIN32 && (SU_HAVE_POLL || HAVE_SELECT) 00439 su_inline 00440 su_socket_t su_wait_socket(su_wait_t *wait) 00441 { 00442 #if SU_HAVE_KQUEUE 00443 return wait->ident; 00444 #else 00445 return wait->fd; 00446 #endif 00447 } 00448 #endif 00449 00450 /* Root */ 00451 SOFIAPUBFUN su_root_t *su_root_create(su_root_magic_t *magic) 00452 __attribute__((__malloc__)); 00453 SOFIAPUBFUN void su_root_destroy(su_root_t*); 00454 SOFIAPUBFUN char const *su_root_name(su_root_t *self); 00455 SOFIAPUBFUN int su_root_set_magic(su_root_t *self, su_root_magic_t *magic); 00456 SOFIAPUBFUN su_root_magic_t *su_root_magic(su_root_t *root); 00457 SOFIAPUBFUN int su_root_register(su_root_t*, su_wait_t *, 00458 su_wakeup_f, su_wakeup_arg_t *, 00459 int priority); 00460 /* This is slow. Deprecated. */ 00461 SOFIAPUBFUN int su_root_unregister(su_root_t*, su_wait_t *, 00462 su_wakeup_f, su_wakeup_arg_t*); 00463 SOFIAPUBFUN int su_root_deregister(su_root_t*, int); 00464 SOFIAPUBFUN int su_root_eventmask(su_root_t *, 00465 int index, int socket, int events); 00466 SOFIAPUBFUN su_duration_t su_root_step(su_root_t *root, su_duration_t timeout); 00467 SOFIAPUBFUN su_duration_t su_root_sleep(su_root_t *root, su_duration_t); 00468 SOFIAPUBFUN int su_root_multishot(su_root_t *root, int multishot); 00469 SOFIAPUBFUN void su_root_run(su_root_t *root); 00470 SOFIAPUBFUN void su_root_break(su_root_t *root); 00471 SOFIAPUBFUN _su_task_r su_root_task(su_root_t const *root); 00472 SOFIAPUBFUN _su_task_r su_root_parent(su_root_t const *root); 00473 00474 SOFIAPUBFUN int su_root_add_prepoll(su_root_t *root, 00475 su_prepoll_f *, 00476 su_prepoll_magic_t *); 00477 SOFIAPUBFUN int su_root_remove_prepoll(su_root_t *root); 00478 00479 SOFIAPUBFUN struct _GSource *su_root_gsource(su_root_t *self); 00480 00481 SOFIAPUBFUN int su_root_yield(su_root_t *root); 00482 00483 SOFIAPUBFUN int su_root_release(su_root_t *root); 00484 SOFIAPUBFUN int su_root_obtain(su_root_t *root); 00485 SOFIAPUBFUN int su_root_has_thread(su_root_t *root); 00486 00487 /* Timers */ 00488 SOFIAPUBFUN su_timer_t *su_timer_create(su_task_r const, su_duration_t msec) 00489 __attribute__((__malloc__)); 00490 SOFIAPUBFUN void su_timer_destroy(su_timer_t *); 00491 SOFIAPUBFUN int su_timer_set(su_timer_t *, su_timer_f, su_timer_arg_t *); 00492 SOFIAPUBFUN int su_timer_set_interval(su_timer_t *t, su_timer_f, 00493 su_timer_arg_t *, su_duration_t); 00494 SOFIAPUBFUN int su_timer_set_at(su_timer_t *, su_timer_f, 00495 su_timer_arg_t *, su_time_t); 00496 SOFIAPUBFUN int su_timer_run(su_timer_t *, su_timer_f, su_timer_arg_t *); 00497 SOFIAPUBFUN int su_timer_set_for_ever(su_timer_t *, su_timer_f, 00498 su_timer_arg_t *); 00499 SOFIAPUBFUN int su_timer_reset(su_timer_t *); 00500 00501 SOFIAPUBFUN su_root_t *su_timer_root(su_timer_t const *); 00502 00503 SOFIAPUBFUN int su_timer_expire(su_timer_queue_t * const, 00504 su_duration_t *tout, 00505 su_time_t now); 00506 00507 /* Tasks */ 00508 00510 SOFIAPUBVAR su_task_r const su_task_null; 00511 00512 SOFIAPUBFUN _su_task_r su_task_init(su_task_r task); 00513 SOFIAPUBFUN void su_task_deinit(su_task_r task); 00514 00515 SOFIAPUBFUN void su_task_copy(su_task_r dst, su_task_r const src); 00516 SOFIAPUBFUN void su_task_move(su_task_r dst, su_task_r src); 00517 SOFIAPUBFUN int su_task_cmp(su_task_r const, su_task_r const); 00518 SOFIAPUBFUN int su_task_is_running(su_task_r const); 00519 00520 SOFIAPUBFUN su_root_t *su_task_root(su_task_r const self); 00521 SOFIAPUBFUN su_timer_queue_t *su_task_timers(su_task_r const self); 00522 00523 SOFIAPUBFUN int su_task_execute(su_task_r const task, 00524 int (*function)(void *), void *arg, 00525 int *return_value); 00526 00527 /* Messages */ 00528 SOFIAPUBFUN int su_msg_create(su_msg_r msg, 00529 su_task_r const to, su_task_r const from, 00530 su_msg_f wakeup, isize_t size); 00531 SOFIAPUBFUN int su_msg_report(su_msg_r msg, su_msg_f report); 00532 SOFIAPUBFUN int su_msg_deinitializer(su_msg_r msg, su_msg_deinit_function *); 00533 SOFIAPUBFUN int su_msg_reply(su_msg_r reply, su_msg_cr msg, 00534 su_msg_f wakeup, isize_t size); 00535 SOFIAPUBFUN void su_msg_destroy(su_msg_r msg); 00536 SOFIAPUBFUN void su_msg_save(su_msg_r msg, su_msg_r msg0); 00537 SOFIAPUBFUN void su_msg_remove_refs(su_msg_cr msg); 00538 SOFIAPUBFUN su_msg_arg_t *su_msg_data(su_msg_cr msg); 00539 SOFIAPUBFUN isize_t su_msg_size(su_msg_cr msg); 00540 SOFIAPUBFUN _su_task_r su_msg_from(su_msg_cr msg); 00541 SOFIAPUBFUN _su_task_r su_msg_to(su_msg_cr msg); 00542 SOFIAPUBFUN int su_msg_send(su_msg_r msg); 00543 00544 SOFIAPUBFUN int su_msg_new(su_msg_r msg, size_t size); 00545 SOFIAPUBFUN int su_msg_send_to(su_msg_r msg, 00546 su_task_r const to, 00547 su_msg_f wakeup); 00548 00550 #if SU_HAVE_INLINE 00551 static SU_INLINE 00552 int su_msg_is_non_null(su_msg_cr msg) 00553 { 00554 return msg && *msg != NULL; 00555 } 00556 #else 00557 #define su_msg_is_non_null(msg) ((msg) && (*(msg)) != NULL) 00558 #endif 00559 00560 /* Clones */ 00561 SOFIAPUBFUN int su_root_threading(su_root_t *self, int enable); 00562 SOFIAPUBFUN int su_clone_start(su_root_t *root, 00563 su_clone_r, 00564 su_root_magic_t *magic, 00565 su_root_init_f, 00566 su_root_deinit_f); 00567 SOFIAPUBFUN _su_task_r su_clone_task(su_clone_r); 00568 SOFIAPUBFUN void su_clone_forget(su_clone_r); 00569 SOFIAPUBFUN void su_clone_stop(su_clone_r); 00570 SOFIAPUBFUN void su_clone_wait(su_root_t *root, su_clone_r clone); 00571 00572 SOFIAPUBFUN int su_clone_pause(su_clone_r); 00573 SOFIAPUBFUN int su_clone_resume(su_clone_r); 00574 00575 /* ---------------------------------------------------------------------- */ 00576 /* Different su_root_t implementations */ 00577 00578 typedef su_port_t *su_port_create_f(void); 00579 typedef int su_clone_start_f(su_root_t *parent, 00580 su_clone_r return_clone, 00581 su_root_magic_t *magic, 00582 su_root_init_f init, 00583 su_root_deinit_f deinit); 00584 00585 SOFIAPUBFUN void su_port_prefer(su_port_create_f *f, su_clone_start_f *); 00586 00587 SOFIAPUBFUN su_port_create_f su_default_port_create; 00588 SOFIAPUBFUN su_port_create_f su_epoll_port_create; 00589 SOFIAPUBFUN su_port_create_f su_poll_port_create; 00590 SOFIAPUBFUN su_port_create_f su_wsaevent_port_create; 00591 SOFIAPUBFUN su_port_create_f su_select_port_create; 00592 SOFIAPUBFUN su_port_create_f su_kqueue_port_create; 00593 SOFIAPUBFUN su_port_create_f su_devpoll_port_create; 00594 00595 SOFIAPUBFUN su_clone_start_f su_default_clone_start; 00596 SOFIAPUBFUN su_clone_start_f su_epoll_clone_start; 00597 SOFIAPUBFUN su_clone_start_f su_poll_clone_start; 00598 SOFIAPUBFUN su_clone_start_f su_wsaevent_clone_start; 00599 SOFIAPUBFUN su_clone_start_f su_select_clone_start; 00600 SOFIAPUBFUN su_clone_start_f su_kqueue_clone_start; 00601 SOFIAPUBFUN su_clone_start_f su_devpoll_clone_start; 00602 00603 SOFIA_END_DECLS 00604 00605 #endif /* SU_WAIT_H */