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