su_port.h 16.4 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2 3 4 5 6 7
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2005 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
8
 * This library is free software; you can redistribute it and/or
Pekka Pessi's avatar
Pekka Pessi committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

25 26
#ifndef SU_PORT_H
/** Defined when <su_port.h> has been included. */
Pekka Pessi's avatar
Pekka Pessi committed
27
#define SU_PORT_H
Pekka Pessi's avatar
Pekka Pessi committed
28

Pekka Pessi's avatar
Pekka Pessi committed
29
/**@internal @file su_port.h 
Pekka Pessi's avatar
Pekka Pessi committed
30 31 32 33 34 35 36 37 38 39
 *
 * @brief Internal OS-independent syncronization interface.
 *
 * This looks like the "reactor" pattern.
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
 * 
 * @date Created: Fri May 12 14:13:34 2000 ppessi
 */

40 41 42 43
#ifndef SU_MSG_ARG_T
#define SU_MSG_ARG_T union { char anoymous[4]; }
#endif

Pekka Pessi's avatar
Pekka Pessi committed
44
#ifndef SU_WAIT_H
45
#include "sofia-sip/su_wait.h"
Pekka Pessi's avatar
Pekka Pessi committed
46 47 48
#endif

#ifndef SU_MODULE_DEBUG_H
49
#include "su_module_debug.h"
Pekka Pessi's avatar
Pekka Pessi committed
50 51 52
#endif

#ifndef SU_ALLOC_H
53
#include <sofia-sip/su_alloc.h>
Pekka Pessi's avatar
Pekka Pessi committed
54 55
#endif

56 57
#include <assert.h>

58
#define SU_WAIT_MIN    (16)
Pekka Pessi's avatar
Pekka Pessi committed
59

60
SOFIA_BEGIN_DECLS
Pekka Pessi's avatar
Pekka Pessi committed
61

Pekka Pessi's avatar
Pekka Pessi committed
62
/** @internal Message */
Pekka Pessi's avatar
Pekka Pessi committed
63
struct su_msg_s {
64
  isize_t        sum_size;
Pekka Pessi's avatar
Pekka Pessi committed
65 66 67 68 69 70 71 72 73 74
  su_msg_t      *sum_next;
  su_task_r      sum_to;
  su_task_r      sum_from;
  su_msg_f       sum_func;
  su_msg_f       sum_report;
  su_msg_arg_t   sum_data[1];		/* minimum size, may be extended */
};

struct _GSource;

Pekka Pessi's avatar
Pekka Pessi committed
75
/** @internal Root structure */
Pekka Pessi's avatar
Pekka Pessi committed
76 77 78 79 80 81 82 83 84 85 86 87
struct su_root_s {
  int              sur_size;
  su_root_magic_t *sur_magic;
  su_root_deinit_f sur_deinit;
  su_task_r        sur_task;
  su_task_r        sur_parent;
  unsigned         sur_threading : 1;
  unsigned         sur_deiniting : 1;
};

#define SU_ROOT_MAGIC(r) ((r) ? (r)->sur_magic : NULL)

88 89 90 91 92 93
enum su_port_thread_op {
  su_port_thread_op_is_obtained,
  su_port_thread_op_release,
  su_port_thread_op_obtain
};
  
Pekka Pessi's avatar
Pekka Pessi committed
94
/** @internal Virtual function table for port */
95
typedef struct su_port_vtable {
Pekka Pessi's avatar
Pekka Pessi committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
  unsigned su_vtable_size;
  void (*su_port_lock)(su_port_t *port, char const *who);
  void (*su_port_unlock)(su_port_t *port, char const *who);
  void (*su_port_incref)(su_port_t *port, char const *who);
  void (*su_port_decref)(su_port_t *port, int block, char const *who);
  struct _GSource *(*su_port_gsource)(su_port_t *port);
  int (*su_port_send)(su_port_t *self, su_msg_r rmsg);
  int (*su_port_register)(su_port_t *self,
		       su_root_t *root, 
		       su_wait_t *wait, 
		       su_wakeup_f callback,
		       su_wakeup_arg_t *arg,
		       int priority);
  int (*su_port_unregister)(su_port_t *port,
			    su_root_t *root, 
			    su_wait_t *wait,	
			    su_wakeup_f callback, 
			    su_wakeup_arg_t *arg);
  int (*su_port_deregister)(su_port_t *self, int i);
  int (*su_port_unregister_all)(su_port_t *self,
			     su_root_t *root);
  int (*su_port_eventmask)(su_port_t *self, int index, int socket, int events);
  void (*su_port_run)(su_port_t *self);
  void (*su_port_break)(su_port_t *self);
  su_duration_t (*su_port_step)(su_port_t *self, su_duration_t tout);
  
122 123
  /* Reused slot */
  int (*su_port_thread)(su_port_t *port, enum su_port_thread_op op);
Pekka Pessi's avatar
Pekka Pessi committed
124 125 126 127 128 129 130 131 132
  
  int (*su_port_add_prepoll)(su_port_t *port,
			     su_root_t *root, 
			     su_prepoll_f *, 
			     su_prepoll_magic_t *);
  
  int (*su_port_remove_prepoll)(su_port_t *port,
				su_root_t *root);

133
  su_timer_queue_t *(*su_port_timers)(su_port_t *port);
Pekka Pessi's avatar
Pekka Pessi committed
134 135 136 137

  int (*su_port_multishot)(su_port_t *port, int multishot);

  int (*su_port_threadsafe)(su_port_t *port);
138 139
  /* Extension from > 1.12.0 */
  int (*su_port_yield)(su_port_t *port);
140 141 142
  /* Extension from >= 1.12.4 */
  int (*su_port_wait_events)(su_port_t *port, su_duration_t timeout);
  int (*su_port_getmsgs)(su_port_t *port);
143 144 145 146 147 148 149 150
  /* Extension from >= 1.12.5 */
  int (*su_port_getmsgs_from)(su_port_t *port, su_port_t *cloneport);
  char const *(*su_port_name)(su_port_t const *port);
  int (*su_port_start_shared)(su_root_t *root,
			      su_clone_r return_clone,
			      su_root_magic_t *magic,
			      su_root_init_f init,
			      su_root_deinit_f deinit);
151 152 153 154
  void (*su_port_wait)(su_clone_r rclone);
  int (*su_port_execute)(su_task_r const task,
			 int (*function)(void *), void *arg,
			 int *return_value);  
Pekka Pessi's avatar
Pekka Pessi committed
155 156
} su_port_vtable_t;

Pekka Pessi's avatar
Pekka Pessi committed
157
SOFIAPUBFUN su_port_t *su_port_create(void)
Pekka Pessi's avatar
Pekka Pessi committed
158 159
     __attribute__((__malloc__));

160
/* Extension from >= 1.12.5 */
161

Pekka Pessi's avatar
Pekka Pessi committed
162 163 164 165
SOFIAPUBFUN void su_msg_delivery_report(su_msg_r msg);
SOFIAPUBFUN su_duration_t su_timer_next_expires(su_timer_t const * t,
						su_time_t now);
SOFIAPUBFUN su_root_t *su_root_create_with_port(su_root_magic_t *magic,
166 167
						su_port_t *port)
  __attribute__((__malloc__));
Pekka Pessi's avatar
Pekka Pessi committed
168

169 170 171 172
/* Extension from >= 1.12.6 */

SOFIAPUBFUN char const *su_port_name(su_port_t const *port);

173 174 175 176 177 178 179 180 181 182 183
/* ---------------------------------------------------------------------- */

/* React to multiple events per one poll() to make sure 
 * that high-priority events can never completely mask other events.
 * Enabled by default on all platforms except WIN32 */
#if !defined(WIN32)
#define SU_ENABLE_MULTISHOT_POLL 1
#else
#define SU_ENABLE_MULTISHOT_POLL 0
#endif

184 185
/* ---------------------------------------------------------------------- */
/* Virtual functions */
Pekka Pessi's avatar
Pekka Pessi committed
186

187 188
typedef struct su_virtual_port_s {
  su_home_t        sup_home[1];
Pekka Pessi's avatar
Pekka Pessi committed
189
  su_port_vtable_t const *sup_vtable;
190 191
} su_virtual_port_t;

192
su_inline
193 194 195 196
su_home_t *su_port_home(su_port_t const *self)
{
  return (su_home_t *)self;
}
Pekka Pessi's avatar
Pekka Pessi committed
197

198
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
199 200
void su_port_lock(su_port_t *self, char const *who)
{
201
  su_virtual_port_t *base = (su_virtual_port_t *)self;
202
  base->sup_vtable->su_port_lock(self, who);
Pekka Pessi's avatar
Pekka Pessi committed
203 204
}

205
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
206 207
void su_port_unlock(su_port_t *self, char const *who)
{
208
  su_virtual_port_t *base = (su_virtual_port_t *)self;
209
  base->sup_vtable->su_port_unlock(self, who);
Pekka Pessi's avatar
Pekka Pessi committed
210 211
}

212
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
213 214
void su_port_incref(su_port_t *self, char const *who)
{
215
  su_virtual_port_t *base = (su_virtual_port_t *)self;
216
  base->sup_vtable->su_port_incref(self, who);
Pekka Pessi's avatar
Pekka Pessi committed
217 218
}

219
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
220 221
void su_port_decref(su_port_t *self, char const *who)
{
222
  su_virtual_port_t *base = (su_virtual_port_t *)self;
223
  base->sup_vtable->su_port_decref(self, 0, who);
Pekka Pessi's avatar
Pekka Pessi committed
224 225
}

226
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
227 228
void su_port_zapref(su_port_t *self, char const *who)
{
229
  su_virtual_port_t *base = (su_virtual_port_t *)self;
230
  base->sup_vtable->su_port_decref(self, 1, who);
Pekka Pessi's avatar
Pekka Pessi committed
231 232
}

233
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
234 235
struct _GSource *su_port_gsource(su_port_t *self)
{
236
  su_virtual_port_t *base = (su_virtual_port_t *)self;
237
  return base->sup_vtable->su_port_gsource(self);
Pekka Pessi's avatar
Pekka Pessi committed
238 239
}

240
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
241 242
int su_port_send(su_port_t *self, su_msg_r rmsg)
{
243
  su_virtual_port_t *base = (su_virtual_port_t *)self;
244
  return base->sup_vtable->su_port_send(self, rmsg);
Pekka Pessi's avatar
Pekka Pessi committed
245 246 247
}


248
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
249 250 251 252 253 254 255
int su_port_register(su_port_t *self,
		     su_root_t *root, 
		     su_wait_t *wait, 
		     su_wakeup_f callback,
		     su_wakeup_arg_t *arg,
		     int priority)
{
256
  su_virtual_port_t *base = (su_virtual_port_t *)self;
257 258
  return base->sup_vtable->
    su_port_register(self, root, wait, callback, arg, priority);
Pekka Pessi's avatar
Pekka Pessi committed
259 260
}

261
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
262 263 264 265 266 267
int su_port_unregister(su_port_t *self,
		       su_root_t *root, 
		       su_wait_t *wait,	
		       su_wakeup_f callback, 
		       su_wakeup_arg_t *arg)
{
268
  su_virtual_port_t *base = (su_virtual_port_t *)self;
269 270
  return base->sup_vtable->
    su_port_unregister(self, root, wait, callback, arg);
Pekka Pessi's avatar
Pekka Pessi committed
271 272
}

273
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
274 275
int su_port_deregister(su_port_t *self, int i)
{
276
  su_virtual_port_t *base = (su_virtual_port_t *)self;
277 278
  return base->sup_vtable->
    su_port_deregister(self, i);
Pekka Pessi's avatar
Pekka Pessi committed
279 280
}

281
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
282 283 284
int su_port_unregister_all(su_port_t *self,
			   su_root_t *root)
{
285
  su_virtual_port_t *base = (su_virtual_port_t *)self;
286 287
  return base->sup_vtable->
    su_port_unregister_all(self, root);
Pekka Pessi's avatar
Pekka Pessi committed
288 289
}

290
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
291 292
int su_port_eventmask(su_port_t *self, int index, int socket, int events)
{
293
  su_virtual_port_t *base = (su_virtual_port_t *)self;
294 295 296 297 298 299 300 301 302 303 304 305
  return base->sup_vtable->
    su_port_eventmask(self, index, socket, events);
}

su_inline
int su_port_wait_events(su_port_t *self, su_duration_t timeout)
{
  su_virtual_port_t *base = (su_virtual_port_t *)self;
  if (base->sup_vtable->su_port_wait_events == NULL)
    return errno = ENOSYS, -1;
  return base->sup_vtable->
    su_port_wait_events(self, timeout);
Pekka Pessi's avatar
Pekka Pessi committed
306 307
}

308
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
309 310
void su_port_run(su_port_t *self)
{
311
  su_virtual_port_t *base = (su_virtual_port_t *)self;
312
  base->sup_vtable->su_port_run(self);
Pekka Pessi's avatar
Pekka Pessi committed
313 314
}

315
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
316 317
void su_port_break(su_port_t *self)
{
318
  su_virtual_port_t *base = (su_virtual_port_t *)self;
319
  base->sup_vtable->su_port_break(self);
Pekka Pessi's avatar
Pekka Pessi committed
320 321
}

322
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
323 324
su_duration_t su_port_step(su_port_t *self, su_duration_t tout)
{
325
  su_virtual_port_t *base = (su_virtual_port_t *)self;
326
  return base->sup_vtable->su_port_step(self, tout);
Pekka Pessi's avatar
Pekka Pessi committed
327 328
}

329

330
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
331 332
int su_port_own_thread(su_port_t const *self)
{
333
  su_virtual_port_t const *base = (su_virtual_port_t *)self;
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
  return base->sup_vtable->
    su_port_thread((su_port_t *)self, su_port_thread_op_is_obtained) == 2;
}

su_inline int su_port_has_thread(su_port_t *self)
{
  su_virtual_port_t *base = (su_virtual_port_t *)self;
  return base->sup_vtable->su_port_thread(self, su_port_thread_op_is_obtained);
}

su_inline int su_port_release(su_port_t *self)
{
  su_virtual_port_t *base = (su_virtual_port_t *)self;
  return base->sup_vtable->su_port_thread(self, su_port_thread_op_release);
}

su_inline int su_port_obtain(su_port_t *self)
{
  su_virtual_port_t *base = (su_virtual_port_t *)self;
  return base->sup_vtable->su_port_thread(self, su_port_thread_op_obtain);
Pekka Pessi's avatar
Pekka Pessi committed
354 355
}

356
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
357 358 359 360 361
int su_port_add_prepoll(su_port_t *self,
			su_root_t *root, 
			su_prepoll_f *prepoll, 
			su_prepoll_magic_t *magic)
{
362
  su_virtual_port_t *base = (su_virtual_port_t *)self;
363
  return base->sup_vtable->su_port_add_prepoll(self, root, prepoll, magic);
Pekka Pessi's avatar
Pekka Pessi committed
364 365
}

366
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
367 368 369
int su_port_remove_prepoll(su_port_t *self,
			   su_root_t *root)
{
370
  su_virtual_port_t *base = (su_virtual_port_t *)self;
371
  return base->sup_vtable->su_port_remove_prepoll(self, root);
Pekka Pessi's avatar
Pekka Pessi committed
372 373
}

374
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
375 376
su_timer_t **su_port_timers(su_port_t *self)
{
377
  su_virtual_port_t *base = (su_virtual_port_t *)self;
378
  return base->sup_vtable->su_port_timers(self);
Pekka Pessi's avatar
Pekka Pessi committed
379 380
}

381
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
382 383
int su_port_multishot(su_port_t *self, int multishot)
{
384
  su_virtual_port_t *base = (su_virtual_port_t *)self;
385
  return base->sup_vtable->su_port_multishot(self, multishot);
Pekka Pessi's avatar
Pekka Pessi committed
386 387
}

388
su_inline
Pekka Pessi's avatar
Pekka Pessi committed
389 390
int su_port_threadsafe(su_port_t *self)
{
391
  su_virtual_port_t *base = (su_virtual_port_t *)self;
392
  return base->sup_vtable->su_port_threadsafe(self);
Pekka Pessi's avatar
Pekka Pessi committed
393 394
}

395
su_inline
396 397 398 399 400 401
int su_port_getmsgs(su_port_t *self)
{
  su_virtual_port_t *base = (su_virtual_port_t *)self;
  return base->sup_vtable->su_port_getmsgs(self);
}

402
su_inline
403 404 405 406 407 408
int su_port_getmsgs_from(su_port_t *self, su_port_t *cloneport)
{
  su_virtual_port_t *base = (su_virtual_port_t *)self;
  return base->sup_vtable->su_port_getmsgs_from(self, cloneport);
}

409 410 411 412 413 414
SOFIAPUBFUN void su_port_wait(su_clone_r rclone);

SOFIAPUBFUN int su_port_execute(su_task_r const task,
				int (*function)(void *), void *arg,
				int *return_value);

415 416
/* ---------------------------------------------------------------------- */

Pekka Pessi's avatar
Pekka Pessi committed
417
/**@internal Base port object.
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
 *
 * Port is a per-thread reactor. Multiple root objects executed by a single
 * thread share the su_port_t object.
 */
typedef struct su_base_port_s {
  su_home_t        sup_home[1];
  su_port_vtable_t const *sup_vtable;

  /* Implementation may vary stuff below, too. */
  
  /* Pre-poll callback */
  su_prepoll_f    *sup_prepoll; 
  su_prepoll_magic_t *sup_pp_magic;
  su_root_t       *sup_pp_root;

  /* Message list - this is protected by su_port_lock()/su_port_unlock() */
  su_msg_t        *sup_head, **sup_tail;

  /* Timer list */
437
  su_timer_queue_t sup_timers;
438 439 440 441 442 443 444 445 446 447 448 449

  unsigned         sup_running;	  /**< In su_root_run() loop? */
} su_base_port_t;

/* Base methods */

SOFIAPUBFUN int su_base_port_init(su_port_t *, su_port_vtable_t const *);
SOFIAPUBFUN void su_base_port_deinit(su_port_t *self);

SOFIAPUBFUN void su_base_port_lock(su_port_t *self, char const *who);
SOFIAPUBFUN void su_base_port_unlock(su_port_t *self, char const *who);

450 451
SOFIAPUBFUN int su_base_port_thread(su_port_t const *self,
				    enum su_port_thread_op op);
452 453 454 455 456 457 458 459 460 461 462

SOFIAPUBFUN void su_base_port_incref(su_port_t *self, char const *who);
SOFIAPUBFUN int su_base_port_decref(su_port_t *self,
				    int blocking,
				    char const *who);

SOFIAPUBFUN struct _GSource *su_base_port_gsource(su_port_t *self);

SOFIAPUBFUN su_socket_t su_base_port_mbox(su_port_t *self);
SOFIAPUBFUN int su_base_port_send(su_port_t *self, su_msg_r rmsg);
SOFIAPUBFUN int su_base_port_getmsgs(su_port_t *self);
463 464
SOFIAPUBFUN int su_base_port_getmsgs_from(su_port_t *self,
					   su_port_t *from);
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480

SOFIAPUBFUN void su_base_port_run(su_port_t *self);
SOFIAPUBFUN void su_base_port_break(su_port_t *self);
SOFIAPUBFUN su_duration_t su_base_port_step(su_port_t *self,
					    su_duration_t tout);

SOFIAPUBFUN int su_base_port_add_prepoll(su_port_t *self,
					 su_root_t *root, 
					 su_prepoll_f *, 
					 su_prepoll_magic_t *);

SOFIAPUBFUN int su_base_port_remove_prepoll(su_port_t *self, su_root_t *root);

SOFIAPUBFUN su_timer_t **su_base_port_timers(su_port_t *self);

SOFIAPUBFUN int su_base_port_multishot(su_port_t *self, int multishot);
481

482
SOFIAPUBFUN int su_base_port_threadsafe(su_port_t *self);
483

484 485
SOFIAPUBFUN int su_base_port_yield(su_port_t *self);

486 487 488 489 490
SOFIAPUBFUN int su_base_port_start_shared(su_root_t *parent,
					  su_clone_r return_clone,
					  su_root_magic_t *magic,
					  su_root_init_f init,
					  su_root_deinit_f deinit);
491 492
SOFIAPUBFUN void su_base_port_wait(su_clone_r rclone);

493 494 495 496 497 498
/* ---------------------------------------------------------------------- */

#if SU_HAVE_PTHREADS

#include <pthread.h>

Pekka Pessi's avatar
Pekka Pessi committed
499
/** @internal Pthread port object */ 
500 501
typedef struct su_pthread_port_s {
  su_base_port_t   sup_base[1];
502 503
  struct su_pthread_port_waiting_parent 
                  *sup_waiting_parent;
504
  pthread_t        sup_tid;
505 506
  pthread_mutex_t  sup_obtained[1];

507
#if 0
508
  pthread_mutex_t  sup_runlock[1];
509 510 511 512
  pthread_cond_t   sup_resume[1];
  short            sup_paused;	/**< True if thread is paused */
#endif
  short            sup_thread;	/**< True if thread is active */
513 514 515 516 517 518 519 520 521 522
} su_pthread_port_t;

/* Pthread methods */

SOFIAPUBFUN int su_pthread_port_init(su_port_t *, su_port_vtable_t const *);
SOFIAPUBFUN void su_pthread_port_deinit(su_port_t *self);

SOFIAPUBFUN void su_pthread_port_lock(su_port_t *self, char const *who);
SOFIAPUBFUN void su_pthread_port_unlock(su_port_t *self, char const *who);

523 524
SOFIAPUBFUN int su_pthread_port_thread(su_port_t *self,
				       enum su_port_thread_op op);
525

526
#if 0				/* not yet  */
527 528
SOFIAPUBFUN int su_pthread_port_send(su_port_t *self, su_msg_r rmsg);

529
SOFIAPUBFUN su_port_t *su_pthread_port_create(void);
530 531 532 533 534 535 536 537 538 539 540 541 542
SOFIAPUBFUN su_port_t *su_pthread_port_start(su_root_t *parent,
					     su_clone_r return_clone,
					     su_root_magic_t *magic,
					     su_root_init_f init,
					     su_root_deinit_f deinit);
#endif

SOFIAPUBFUN int su_pthreaded_port_start(su_port_create_f *create,
					su_root_t *parent,
					su_clone_r return_clone,
					su_root_magic_t *magic,
					su_root_init_f init,
					su_root_deinit_f deinit);
543 544 545 546 547 548

SOFIAPUBFUN void su_pthread_port_wait(su_clone_r rclone);
SOFIAPUBFUN int su_pthread_port_execute(su_task_r const task,
					int (*function)(void *), void *arg,
					int *return_value);

549

550 551 552 553 554
#if 0
SOFIAPUBFUN int su_pthread_port_pause(su_port_t *self);
SOFIAPUBFUN int su_pthread_port_resume(su_port_t *self);
#endif

555 556 557 558 559 560 561 562
#else

typedef su_base_port_t su_pthread_port_t;

#define su_pthread_port_init   su_base_port_init
#define su_pthread_port_deinit su_base_port_deinit
#define su_pthread_port_lock   su_base_port_lock
#define su_pthread_port_unlock su_base_port_unlock
563
#define su_pthread_port_thread su_base_port_thread
564 565
#define su_pthread_port_wait   su_base_port_wait
#define su_pthread_port_execute  su_base_port_execute
Pekka Pessi's avatar
Pekka Pessi committed
566 567 568

#endif

569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
/* ====================================================================== */
/* Mailbox port using sockets */

#define SU_MBOX_SIZE 2

typedef struct su_socket_port_s {
  su_pthread_port_t sup_base[1];
  int               sup_mbox_index;
  su_socket_t       sup_mbox[SU_MBOX_SIZE];
} su_socket_port_t;

SOFIAPUBFUN int su_socket_port_init(su_socket_port_t *, 
				    su_port_vtable_t const *);
SOFIAPUBFUN void su_socket_port_deinit(su_socket_port_t *self);
SOFIAPUBFUN int su_socket_port_send(su_port_t *self, su_msg_r rmsg);

585 586
SOFIA_END_DECLS

Pekka Pessi's avatar
Pekka Pessi committed
587
#endif /* SU_PORT_H */