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