sofia-sip/su_wait.h

Go to the documentation of this file.
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 */

Sofia-SIP 1.12.8 - Copyright (C) 2006 Nokia Corporation. All rights reserved. Licensed under the terms of the GNU Lesser General Public License.