00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SU_PORT_H
00026
00027 #define SU_PORT_H
00028
00040 #ifndef SU_MSG_ARG_T
00041 #define SU_MSG_ARG_T union { char anoymous[4]; }
00042 #endif
00043
00044 #ifndef SU_WAIT_H
00045 #include "sofia-sip/su_wait.h"
00046 #endif
00047
00048 #ifndef SU_MODULE_DEBUG_H
00049 #include "su_module_debug.h"
00050 #endif
00051
00052 #ifndef SU_ALLOC_H
00053 #include <sofia-sip/su_alloc.h>
00054 #endif
00055
00056 #include <assert.h>
00057
00058 #define SU_WAIT_MIN (16)
00059
00060 SOFIA_BEGIN_DECLS
00061
00063 struct su_msg_s {
00064 isize_t sum_size;
00065 su_msg_t *sum_next;
00066 su_task_r sum_to;
00067 su_task_r sum_from;
00068 su_msg_f sum_func;
00069 su_msg_f sum_report;
00070 su_msg_arg_t sum_data[1];
00071 };
00072
00073 struct _GSource;
00074
00076 struct su_root_s {
00077 int sur_size;
00078 su_root_magic_t *sur_magic;
00079 su_root_deinit_f sur_deinit;
00080 su_task_r sur_task;
00081 su_task_r sur_parent;
00082 unsigned sur_threading : 1;
00083 unsigned sur_deiniting : 1;
00084 };
00085
00086 #define SU_ROOT_MAGIC(r) ((r) ? (r)->sur_magic : NULL)
00087
00089 typedef struct su_port_vtable {
00090 unsigned su_vtable_size;
00091 void (*su_port_lock)(su_port_t *port, char const *who);
00092 void (*su_port_unlock)(su_port_t *port, char const *who);
00093 void (*su_port_incref)(su_port_t *port, char const *who);
00094 void (*su_port_decref)(su_port_t *port, int block, char const *who);
00095 struct _GSource *(*su_port_gsource)(su_port_t *port);
00096 int (*su_port_send)(su_port_t *self, su_msg_r rmsg);
00097 int (*su_port_register)(su_port_t *self,
00098 su_root_t *root,
00099 su_wait_t *wait,
00100 su_wakeup_f callback,
00101 su_wakeup_arg_t *arg,
00102 int priority);
00103 int (*su_port_unregister)(su_port_t *port,
00104 su_root_t *root,
00105 su_wait_t *wait,
00106 su_wakeup_f callback,
00107 su_wakeup_arg_t *arg);
00108 int (*su_port_deregister)(su_port_t *self, int i);
00109 int (*su_port_unregister_all)(su_port_t *self,
00110 su_root_t *root);
00111 int (*su_port_eventmask)(su_port_t *self, int index, int socket, int events);
00112 void (*su_port_run)(su_port_t *self);
00113 void (*su_port_break)(su_port_t *self);
00114 su_duration_t (*su_port_step)(su_port_t *self, su_duration_t tout);
00115
00116 int (*su_port_own_thread)(su_port_t const *port);
00117
00118 int (*su_port_add_prepoll)(su_port_t *port,
00119 su_root_t *root,
00120 su_prepoll_f *,
00121 su_prepoll_magic_t *);
00122
00123 int (*su_port_remove_prepoll)(su_port_t *port,
00124 su_root_t *root);
00125
00126 su_timer_t **(*su_port_timers)(su_port_t *port);
00127
00128 int (*su_port_multishot)(su_port_t *port, int multishot);
00129
00130 int (*su_port_threadsafe)(su_port_t *port);
00131
00132 int (*su_port_yield)(su_port_t *port);
00133
00134 int (*su_port_wait_events)(su_port_t *port, su_duration_t timeout);
00135 int (*su_port_getmsgs)(su_port_t *port);
00136
00137 int (*su_port_getmsgs_from)(su_port_t *port, su_port_t *cloneport);
00138 char const *(*su_port_name)(su_port_t const *port);
00139 int (*su_port_start_shared)(su_root_t *root,
00140 su_clone_r return_clone,
00141 su_root_magic_t *magic,
00142 su_root_init_f init,
00143 su_root_deinit_f deinit);
00144 void (*su_port_wait)(su_clone_r rclone);
00145 int (*su_port_execute)(su_task_r const task,
00146 int (*function)(void *), void *arg,
00147 int *return_value);
00148 } su_port_vtable_t;
00149
00150 SOFIAPUBFUN su_port_t *su_port_create(void)
00151 __attribute__((__malloc__));
00152
00153
00154
00155 SOFIAPUBFUN void su_msg_delivery_report(su_msg_r msg);
00156 SOFIAPUBFUN su_duration_t su_timer_next_expires(su_timer_t const * t,
00157 su_time_t now);
00158 SOFIAPUBFUN su_root_t *su_root_create_with_port(su_root_magic_t *magic,
00159 su_port_t *port)
00160 __attribute__((__malloc__));
00161
00162
00163
00164 SOFIAPUBFUN char const *su_port_name(su_port_t const *port);
00165
00166
00167
00168
00169
00170
00171 #if !defined(WIN32)
00172 #define SU_ENABLE_MULTISHOT_POLL 1
00173 #else
00174 #define SU_ENABLE_MULTISHOT_POLL 0
00175 #endif
00176
00177
00178
00179
00180 typedef struct su_virtual_port_s {
00181 su_home_t sup_home[1];
00182 su_port_vtable_t const *sup_vtable;
00183 } su_virtual_port_t;
00184
00185 su_inline
00186 su_home_t *su_port_home(su_port_t const *self)
00187 {
00188 return (su_home_t *)self;
00189 }
00190
00191 su_inline
00192 void su_port_lock(su_port_t *self, char const *who)
00193 {
00194 su_virtual_port_t *base = (su_virtual_port_t *)self;
00195 if (base) base->sup_vtable->su_port_lock(self, who);
00196 }
00197
00198 su_inline
00199 void su_port_unlock(su_port_t *self, char const *who)
00200 {
00201 su_virtual_port_t *base = (su_virtual_port_t *)self;
00202 if (base) base->sup_vtable->su_port_unlock(self, who);
00203 }
00204
00205 su_inline
00206 void su_port_incref(su_port_t *self, char const *who)
00207 {
00208 su_virtual_port_t *base = (su_virtual_port_t *)self;
00209 if (base) base->sup_vtable->su_port_incref(self, who);
00210 }
00211
00212 su_inline
00213 void su_port_decref(su_port_t *self, char const *who)
00214 {
00215 su_virtual_port_t *base = (su_virtual_port_t *)self;
00216 if (base) base->sup_vtable->su_port_decref(self, 0, who);
00217 }
00218
00219 su_inline
00220 void su_port_zapref(su_port_t *self, char const *who)
00221 {
00222 su_virtual_port_t *base = (su_virtual_port_t *)self;
00223 if (base) base->sup_vtable->su_port_decref(self, 1, who);
00224 }
00225
00226 su_inline
00227 struct _GSource *su_port_gsource(su_port_t *self)
00228 {
00229 su_virtual_port_t *base = (su_virtual_port_t *)self;
00230 return base ? base->sup_vtable->su_port_gsource(self) : NULL;
00231 }
00232
00233 su_inline
00234 int su_port_send(su_port_t *self, su_msg_r rmsg)
00235 {
00236 su_virtual_port_t *base = (su_virtual_port_t *)self;
00237 if (base)
00238 return base->sup_vtable->su_port_send(self, rmsg);
00239 errno = EINVAL;
00240 return -1;
00241 }
00242
00243
00244 su_inline
00245 int su_port_register(su_port_t *self,
00246 su_root_t *root,
00247 su_wait_t *wait,
00248 su_wakeup_f callback,
00249 su_wakeup_arg_t *arg,
00250 int priority)
00251 {
00252 su_virtual_port_t *base = (su_virtual_port_t *)self;
00253 if (base)
00254 return base->sup_vtable->su_port_register(self, root, wait,
00255 callback, arg, priority);
00256 errno = EINVAL;
00257 return -1;
00258 }
00259
00260 su_inline
00261 int su_port_unregister(su_port_t *self,
00262 su_root_t *root,
00263 su_wait_t *wait,
00264 su_wakeup_f callback,
00265 su_wakeup_arg_t *arg)
00266 {
00267 su_virtual_port_t *base = (su_virtual_port_t *)self;
00268 if (base)
00269 return base->sup_vtable->
00270 su_port_unregister(self, root, wait, callback, arg);
00271 errno = EINVAL;
00272 return -1;
00273 }
00274
00275 su_inline
00276 int su_port_deregister(su_port_t *self, int i)
00277 {
00278 su_virtual_port_t *base = (su_virtual_port_t *)self;
00279 if (base)
00280 return base->sup_vtable->su_port_deregister(self, i);
00281 errno = EINVAL;
00282 return -1;
00283 }
00284
00285 su_inline
00286 int su_port_unregister_all(su_port_t *self,
00287 su_root_t *root)
00288 {
00289 su_virtual_port_t *base = (su_virtual_port_t *)self;
00290 if (base)
00291 return base->sup_vtable->
00292 su_port_unregister_all(self, root);
00293 errno = EINVAL;
00294 return -1;
00295 }
00296
00297 su_inline
00298 int su_port_eventmask(su_port_t *self, int index, int socket, int events)
00299 {
00300 su_virtual_port_t *base = (su_virtual_port_t *)self;
00301 if (base)
00302 return base->sup_vtable->
00303 su_port_eventmask(self, index, socket, events);
00304 assert(base);
00305 errno = EINVAL;
00306 return -1;
00307 }
00308
00309 su_inline
00310 void su_port_run(su_port_t *self)
00311 {
00312 su_virtual_port_t *base = (su_virtual_port_t *)self;
00313 if (base)
00314 base->sup_vtable->su_port_run(self);
00315 }
00316
00317 su_inline
00318 void su_port_break(su_port_t *self)
00319 {
00320 su_virtual_port_t *base = (su_virtual_port_t *)self;
00321 if (base)
00322 base->sup_vtable->su_port_break(self);
00323 }
00324
00325 su_inline
00326 su_duration_t su_port_step(su_port_t *self, su_duration_t tout)
00327 {
00328 su_virtual_port_t *base = (su_virtual_port_t *)self;
00329 if (base)
00330 return base->sup_vtable->su_port_step(self, tout);
00331 errno = EINVAL;
00332 return (su_duration_t)-1;
00333 }
00334
00335
00336 su_inline
00337 int su_port_own_thread(su_port_t const *self)
00338 {
00339 su_virtual_port_t const *base = (su_virtual_port_t *)self;
00340 return base == NULL || base->sup_vtable->su_port_own_thread(self);
00341 }
00342
00343 su_inline
00344 int su_port_add_prepoll(su_port_t *self,
00345 su_root_t *root,
00346 su_prepoll_f *prepoll,
00347 su_prepoll_magic_t *magic)
00348 {
00349 su_virtual_port_t *base = (su_virtual_port_t *)self;
00350 if (base)
00351 return base->sup_vtable->
00352 su_port_add_prepoll(self, root, prepoll, magic);
00353 errno = EINVAL;
00354 return -1;
00355 }
00356
00357 su_inline
00358 int su_port_remove_prepoll(su_port_t *self,
00359 su_root_t *root)
00360 {
00361 su_virtual_port_t *base = (su_virtual_port_t *)self;
00362 if (base)
00363 return base->sup_vtable->su_port_remove_prepoll(self, root);
00364 errno = EINVAL;
00365 return -1;
00366 }
00367
00368 su_inline
00369 su_timer_t **su_port_timers(su_port_t *self)
00370 {
00371 su_virtual_port_t *base = (su_virtual_port_t *)self;
00372 if (base)
00373 return base->sup_vtable->su_port_timers(self);
00374 errno = EINVAL;
00375 return NULL;
00376 }
00377
00378 su_inline
00379 int su_port_multishot(su_port_t *self, int multishot)
00380 {
00381 su_virtual_port_t *base = (su_virtual_port_t *)self;
00382 if (base)
00383 return base->sup_vtable->su_port_multishot(self, multishot);
00384
00385 assert(base);
00386 errno = EINVAL;
00387 return -1;
00388 }
00389
00390 su_inline
00391 int su_port_threadsafe(su_port_t *self)
00392 {
00393 su_virtual_port_t *base = (su_virtual_port_t *)self;
00394 if (base)
00395 return base->sup_vtable->su_port_threadsafe(self);
00396
00397 assert(base);
00398 errno = EINVAL;
00399 return -1;
00400 }
00401
00402 su_inline
00403 int su_port_getmsgs(su_port_t *self)
00404 {
00405 su_virtual_port_t *base = (su_virtual_port_t *)self;
00406
00407 return base->sup_vtable->su_port_getmsgs(self);
00408 }
00409
00410 su_inline
00411 int su_port_getmsgs_from(su_port_t *self, su_port_t *cloneport)
00412 {
00413 su_virtual_port_t *base = (su_virtual_port_t *)self;
00414
00415 return base->sup_vtable->su_port_getmsgs_from(self, cloneport);
00416 }
00417
00418 SOFIAPUBFUN void su_port_wait(su_clone_r rclone);
00419
00420 SOFIAPUBFUN int su_port_execute(su_task_r const task,
00421 int (*function)(void *), void *arg,
00422 int *return_value);
00423
00424
00425
00431 typedef struct su_base_port_s {
00432 su_home_t sup_home[1];
00433 su_port_vtable_t const *sup_vtable;
00434
00435
00436
00437
00438 su_prepoll_f *sup_prepoll;
00439 su_prepoll_magic_t *sup_pp_magic;
00440 su_root_t *sup_pp_root;
00441
00442
00443 su_msg_t *sup_head, **sup_tail;
00444
00445
00446 su_timer_t *sup_timers;
00447
00448 unsigned sup_running;
00449 } su_base_port_t;
00450
00451
00452
00453 SOFIAPUBFUN int su_base_port_init(su_port_t *, su_port_vtable_t const *);
00454 SOFIAPUBFUN void su_base_port_deinit(su_port_t *self);
00455
00456 SOFIAPUBFUN void su_base_port_lock(su_port_t *self, char const *who);
00457 SOFIAPUBFUN void su_base_port_unlock(su_port_t *self, char const *who);
00458
00459 SOFIAPUBFUN int su_base_port_own_thread(su_port_t const *self);
00460
00461 SOFIAPUBFUN void su_base_port_incref(su_port_t *self, char const *who);
00462 SOFIAPUBFUN int su_base_port_decref(su_port_t *self,
00463 int blocking,
00464 char const *who);
00465
00466 SOFIAPUBFUN struct _GSource *su_base_port_gsource(su_port_t *self);
00467
00468 SOFIAPUBFUN su_socket_t su_base_port_mbox(su_port_t *self);
00469 SOFIAPUBFUN int su_base_port_send(su_port_t *self, su_msg_r rmsg);
00470 SOFIAPUBFUN int su_base_port_getmsgs(su_port_t *self);
00471 SOFIAPUBFUN int su_base_port_getmsgs_from(su_port_t *self,
00472 su_port_t *from);
00473
00474 SOFIAPUBFUN void su_base_port_run(su_port_t *self);
00475 SOFIAPUBFUN void su_base_port_break(su_port_t *self);
00476 SOFIAPUBFUN su_duration_t su_base_port_step(su_port_t *self,
00477 su_duration_t tout);
00478
00479 SOFIAPUBFUN int su_base_port_add_prepoll(su_port_t *self,
00480 su_root_t *root,
00481 su_prepoll_f *,
00482 su_prepoll_magic_t *);
00483
00484 SOFIAPUBFUN int su_base_port_remove_prepoll(su_port_t *self, su_root_t *root);
00485
00486 SOFIAPUBFUN su_timer_t **su_base_port_timers(su_port_t *self);
00487
00488 SOFIAPUBFUN int su_base_port_multishot(su_port_t *self, int multishot);
00489 SOFIAPUBFUN int su_base_port_threadsafe(su_port_t *self);
00490 SOFIAPUBFUN int su_base_port_yield(su_port_t *self);
00491
00492 SOFIAPUBFUN int su_base_port_start_shared(su_root_t *parent,
00493 su_clone_r return_clone,
00494 su_root_magic_t *magic,
00495 su_root_init_f init,
00496 su_root_deinit_f deinit);
00497 SOFIAPUBFUN void su_base_port_wait(su_clone_r rclone);
00498
00499
00500
00501 #if SU_HAVE_PTHREADS
00502
00503 #include <pthread.h>
00504
00506 typedef struct su_pthread_port_s {
00507 su_base_port_t sup_base[1];
00508 struct su_pthread_port_waiting_parent
00509 *sup_waiting_parent;
00510 pthread_t sup_tid;
00511 #if 0
00512 pthread_mutex_t sup_runlock[1];
00513 pthread_cond_t sup_resume[1];
00514 short sup_paused;
00515 #endif
00516 short sup_thread;
00517 } su_pthread_port_t;
00518
00519
00520
00521 SOFIAPUBFUN int su_pthread_port_init(su_port_t *, su_port_vtable_t const *);
00522 SOFIAPUBFUN void su_pthread_port_deinit(su_port_t *self);
00523
00524 SOFIAPUBFUN void su_pthread_port_lock(su_port_t *self, char const *who);
00525 SOFIAPUBFUN void su_pthread_port_unlock(su_port_t *self, char const *who);
00526
00527 SOFIAPUBFUN int su_pthread_port_own_thread(su_port_t const *self);
00528
00529 #if 0
00530 SOFIAPUBFUN int su_pthread_port_send(su_port_t *self, su_msg_r rmsg);
00531
00532 SOFIAPUBFUN su_port_t *su_pthread_port_create(void);
00533 SOFIAPUBFUN su_port_t *su_pthread_port_start(su_root_t *parent,
00534 su_clone_r return_clone,
00535 su_root_magic_t *magic,
00536 su_root_init_f init,
00537 su_root_deinit_f deinit);
00538 #endif
00539
00540 SOFIAPUBFUN int su_pthreaded_port_start(su_port_create_f *create,
00541 su_root_t *parent,
00542 su_clone_r return_clone,
00543 su_root_magic_t *magic,
00544 su_root_init_f init,
00545 su_root_deinit_f deinit);
00546
00547 SOFIAPUBFUN void su_pthread_port_wait(su_clone_r rclone);
00548 SOFIAPUBFUN int su_pthread_port_execute(su_task_r const task,
00549 int (*function)(void *), void *arg,
00550 int *return_value);
00551
00552
00553 #if 0
00554 SOFIAPUBFUN int su_pthread_port_pause(su_port_t *self);
00555 SOFIAPUBFUN int su_pthread_port_resume(su_port_t *self);
00556 #endif
00557
00558 #else
00559
00560 typedef su_base_port_t su_pthread_port_t;
00561
00562 #define su_pthread_port_init su_base_port_init
00563 #define su_pthread_port_deinit su_base_port_deinit
00564 #define su_pthread_port_lock su_base_port_lock
00565 #define su_pthread_port_unlock su_base_port_unlock
00566 #define su_pthread_port_own_thread su_base_port_own_thread
00567 #define su_pthread_port_wait su_base_port_wait
00568 #define su_pthread_port_execute su_base_port_execute
00569
00570 #endif
00571
00572
00573
00574
00575 #define SU_MBOX_SIZE 2
00576
00577 typedef struct su_socket_port_s {
00578 su_pthread_port_t sup_base[1];
00579 int sup_mbox_index;
00580 su_socket_t sup_mbox[SU_MBOX_SIZE];
00581 } su_socket_port_t;
00582
00583 SOFIAPUBFUN int su_socket_port_init(su_socket_port_t *,
00584 su_port_vtable_t const *);
00585 SOFIAPUBFUN void su_socket_port_deinit(su_socket_port_t *self);
00586 SOFIAPUBFUN int su_socket_port_send(su_port_t *self, su_msg_r rmsg);
00587
00588 SOFIA_END_DECLS
00589
00590 #endif