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 SOFIA_BEGIN_DECLS
00059
00060
00061 #define SU_MIN_WAITS (16)
00062
00063 #if SU_HAVE_WINSOCK
00064 #define SU_MAX_WAITS (64)
00065 #elif SU_HAVE_POLL
00066
00067 #define SU_MAX_WAITS (1024)
00068 #endif
00069
00071 struct su_msg_s {
00072 int sum_size;
00073 su_msg_t *sum_next;
00074 su_task_r sum_to;
00075 su_task_r sum_from;
00076 su_msg_f sum_func;
00077 su_msg_f sum_report;
00078 su_msg_arg_t sum_data[1];
00079 };
00080
00081 struct _GSource;
00082
00084 struct su_root_s {
00085 int sur_size;
00086 su_root_magic_t *sur_magic;
00087 su_root_deinit_f sur_deinit;
00088 su_task_r sur_task;
00089 su_task_r sur_parent;
00090 unsigned sur_threading : 1;
00091 unsigned sur_deiniting : 1;
00092 };
00093
00094 #define SU_ROOT_MAGIC(r) ((r) ? (r)->sur_magic : NULL)
00095
00097 typedef struct {
00098 unsigned su_vtable_size;
00099 void (*su_port_lock)(su_port_t *port, char const *who);
00100 void (*su_port_unlock)(su_port_t *port, char const *who);
00101 void (*su_port_incref)(su_port_t *port, char const *who);
00102 void (*su_port_decref)(su_port_t *port, int block, char const *who);
00103 struct _GSource *(*su_port_gsource)(su_port_t *port);
00104 int (*su_port_send)(su_port_t *self, su_msg_r rmsg);
00105 int (*su_port_register)(su_port_t *self,
00106 su_root_t *root,
00107 su_wait_t *wait,
00108 su_wakeup_f callback,
00109 su_wakeup_arg_t *arg,
00110 int priority);
00111 int (*su_port_unregister)(su_port_t *port,
00112 su_root_t *root,
00113 su_wait_t *wait,
00114 su_wakeup_f callback,
00115 su_wakeup_arg_t *arg);
00116 int (*su_port_deregister)(su_port_t *self, int i);
00117 int (*su_port_unregister_all)(su_port_t *self,
00118 su_root_t *root);
00119 int (*su_port_eventmask)(su_port_t *self, int index, int socket, int events);
00120 void (*su_port_run)(su_port_t *self);
00121 void (*su_port_break)(su_port_t *self);
00122 su_duration_t (*su_port_step)(su_port_t *self, su_duration_t tout);
00123
00124 int (*su_port_own_thread)(su_port_t const *port);
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_t **(*su_port_timers)(su_port_t *port);
00135
00136 int (*su_port_multishot)(su_port_t *port, int multishot);
00137
00138 int (*su_port_threadsafe)(su_port_t *port);
00139
00140
00141 int (*su_port_yield)(su_port_t *port);
00142 } su_port_vtable_t;
00143
00144 SOFIAPUBFUN su_port_t *su_port_create(void)
00145 __attribute__((__malloc__));
00146
00147 SOFIAPUBFUN void su_msg_delivery_report(su_msg_r msg);
00148 SOFIAPUBFUN su_duration_t su_timer_next_expires(su_timer_t const * t,
00149 su_time_t now);
00150 SOFIAPUBFUN su_root_t *su_root_create_with_port(su_root_magic_t *magic,
00151 su_port_t *port);
00152
00153 #if SU_PORT_IMPLEMENTATION
00154
00155 #else
00156 struct su_port_s {
00157 su_home_t sup_home[1];
00158 su_port_vtable_t const *sup_vtable;
00159 };
00160
00161 static inline
00162 void su_port_lock(su_port_t *self, char const *who)
00163 {
00164 if (self) self->sup_vtable->su_port_lock(self, who);
00165 }
00166
00167 #define SU_PORT_LOCK(p, f) (su_port_lock(p, #f))
00168
00169 static inline
00170 void su_port_unlock(su_port_t *self, char const *who)
00171 {
00172 if (self) self->sup_vtable->su_port_unlock(self, who);
00173 }
00174
00175 #define SU_PORT_UNLOCK(p, f) (su_port_unlock(p, #f))
00176
00177 static inline
00178 void su_port_incref(su_port_t *self, char const *who)
00179 {
00180 if (self) self->sup_vtable->su_port_incref(self, who);
00181 }
00182
00183 #define SU_PORT_INCREF(p, f) (su_port_incref(p, #f))
00184
00185 static inline
00186 void su_port_decref(su_port_t *self, char const *who)
00187 {
00188 if (self) self->sup_vtable->su_port_decref(self, 0, who);
00189 }
00190
00191 #define SU_PORT_DECREF(p, f) (su_port_decref(p, #f))
00192
00193 static inline
00194 void su_port_zapref(su_port_t *self, char const *who)
00195 {
00196 if (self) self->sup_vtable->su_port_decref(self, 1, who);
00197 }
00198
00199 #define SU_PORT_ZAPREF(p, f) (su_port_zapref(p, #f))
00200
00201 static inline
00202 struct _GSource *su_port_gsource(su_port_t *self)
00203 {
00204 return self ? self->sup_vtable->su_port_gsource(self) : NULL;
00205 }
00206
00207
00208 static inline
00209 int su_port_send(su_port_t *self, su_msg_r rmsg)
00210 {
00211 if (self)
00212 return self->sup_vtable->su_port_send(self, rmsg);
00213 errno = EINVAL;
00214 return -1;
00215 }
00216
00217
00218 static inline
00219 int su_port_register(su_port_t *self,
00220 su_root_t *root,
00221 su_wait_t *wait,
00222 su_wakeup_f callback,
00223 su_wakeup_arg_t *arg,
00224 int priority)
00225 {
00226 if (self)
00227 return self->sup_vtable->su_port_register(self, root, wait,
00228 callback, arg, priority);
00229 errno = EINVAL;
00230 return -1;
00231 }
00232
00233 static inline
00234 int su_port_unregister(su_port_t *self,
00235 su_root_t *root,
00236 su_wait_t *wait,
00237 su_wakeup_f callback,
00238 su_wakeup_arg_t *arg)
00239 {
00240 if (self)
00241 return self->sup_vtable->
00242 su_port_unregister(self, root, wait, callback, arg);
00243 errno = EINVAL;
00244 return -1;
00245 }
00246
00247 static inline
00248 int su_port_deregister(su_port_t *self, int i)
00249 {
00250 if (self)
00251 return self->sup_vtable->
00252 su_port_deregister(self, i);
00253 errno = EINVAL;
00254 return -1;
00255 }
00256
00257 static inline
00258 int su_port_unregister_all(su_port_t *self,
00259 su_root_t *root)
00260 {
00261 if (self)
00262 return self->sup_vtable->
00263 su_port_unregister_all(self, root);
00264 errno = EINVAL;
00265 return -1;
00266 }
00267
00268 static inline
00269 int su_port_eventmask(su_port_t *self, int index, int socket, int events)
00270 {
00271 if (self)
00272 return self->sup_vtable->
00273 su_port_eventmask(self, index, socket, events);
00274 assert(self);
00275 errno = EINVAL;
00276 return -1;
00277 }
00278
00279 static inline
00280 void su_port_run(su_port_t *self)
00281 {
00282 if (self)
00283 self->sup_vtable->su_port_run(self);
00284 }
00285
00286 static inline
00287 void su_port_break(su_port_t *self)
00288 {
00289 if (self)
00290 self->sup_vtable->su_port_break(self);
00291 }
00292
00293 static inline
00294 su_duration_t su_port_step(su_port_t *self, su_duration_t tout)
00295 {
00296 if (self)
00297 return self->sup_vtable->su_port_step(self, tout);
00298 errno = EINVAL;
00299 return (su_duration_t)-1;
00300 }
00301
00302
00303 static inline
00304 int su_port_own_thread(su_port_t const *self)
00305 {
00306 return self == NULL || self->sup_vtable->su_port_own_thread(self);
00307 }
00308
00309 static inline
00310 int su_port_add_prepoll(su_port_t *self,
00311 su_root_t *root,
00312 su_prepoll_f *prepoll,
00313 su_prepoll_magic_t *magic)
00314 {
00315 if (self)
00316 return self->sup_vtable->
00317 su_port_add_prepoll(self, root, prepoll, magic);
00318 errno = EINVAL;
00319 return -1;
00320 }
00321
00322 static inline
00323 int su_port_remove_prepoll(su_port_t *self,
00324 su_root_t *root)
00325 {
00326 if (self)
00327 return self->sup_vtable->su_port_remove_prepoll(self, root);
00328 errno = EINVAL;
00329 return -1;
00330 }
00331
00332 static inline
00333 su_timer_t **su_port_timers(su_port_t *self)
00334 {
00335 if (self)
00336 return self->sup_vtable->su_port_timers(self);
00337 errno = EINVAL;
00338 return NULL;
00339 }
00340
00341 static inline
00342 int su_port_multishot(su_port_t *self, int multishot)
00343 {
00344 if (self)
00345 return self->sup_vtable->su_port_multishot(self, multishot);
00346
00347 assert(self);
00348 errno = EINVAL;
00349 return -1;
00350 }
00351
00352 static inline
00353 int su_port_threadsafe(su_port_t *self)
00354 {
00355 if (self)
00356 return self->sup_vtable->su_port_threadsafe(self);
00357
00358 assert(self);
00359 errno = EINVAL;
00360 return -1;
00361 }
00362
00363
00364 #endif
00365
00366 SOFIA_END_DECLS
00367
00368 #endif