freeswitch/libs/sofia-sip/libsofia-sip-ua/su/su_port.h

361 lines
8.2 KiB
C

/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* 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
*
*/
#ifndef SU_PORT_H
/** Defined when <su_port.h> has been included. */
#define SU_PORT_H
/**@IFILE su_port.h
*
* @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
*/
#ifndef SU_MSG_ARG_T
#define SU_MSG_ARG_T union { char anoymous[4]; }
#endif
#ifndef SU_WAIT_H
#include "sofia-sip/su_wait.h"
#endif
#ifndef SU_MODULE_DEBUG_H
#include "su_module_debug.h"
#endif
#ifndef SU_ALLOC_H
#include <sofia-sip/su_alloc.h>
#endif
#include <assert.h>
#define SU_WAIT_MIN (16)
SOFIA_BEGIN_DECLS
/** Message */
struct su_msg_s {
isize_t sum_size;
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;
/** Root structure */
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)
/** Virtual function table for port */
typedef struct {
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);
int (*su_port_own_thread)(su_port_t const *port);
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);
su_timer_t **(*su_port_timers)(su_port_t *port);
int (*su_port_multishot)(su_port_t *port, int multishot);
int (*su_port_threadsafe)(su_port_t *port);
/* Extension from > 1.12.0 */
int (*su_port_yield)(su_port_t *port);
} su_port_vtable_t;
SOFIAPUBFUN su_port_t *su_port_create(void)
__attribute__((__malloc__));
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,
su_port_t *port);
#if SU_PORT_IMPLEMENTATION
#else
struct su_port_s {
su_home_t sup_home[1];
su_port_vtable_t const *sup_vtable;
};
static inline
void su_port_lock(su_port_t *self, char const *who)
{
if (self) self->sup_vtable->su_port_lock(self, who);
}
#define SU_PORT_LOCK(p, f) (su_port_lock(p, #f))
static inline
void su_port_unlock(su_port_t *self, char const *who)
{
if (self) self->sup_vtable->su_port_unlock(self, who);
}
#define SU_PORT_UNLOCK(p, f) (su_port_unlock(p, #f))
static inline
void su_port_incref(su_port_t *self, char const *who)
{
if (self) self->sup_vtable->su_port_incref(self, who);
}
#define SU_PORT_INCREF(p, f) (su_port_incref(p, #f))
static inline
void su_port_decref(su_port_t *self, char const *who)
{
if (self) self->sup_vtable->su_port_decref(self, 0, who);
}
#define SU_PORT_DECREF(p, f) (su_port_decref(p, #f))
static inline
void su_port_zapref(su_port_t *self, char const *who)
{
if (self) self->sup_vtable->su_port_decref(self, 1, who);
}
#define SU_PORT_ZAPREF(p, f) (su_port_zapref(p, #f))
static inline
struct _GSource *su_port_gsource(su_port_t *self)
{
return self ? self->sup_vtable->su_port_gsource(self) : NULL;
}
static inline
int su_port_send(su_port_t *self, su_msg_r rmsg)
{
if (self)
return self->sup_vtable->su_port_send(self, rmsg);
errno = EINVAL;
return -1;
}
static inline
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)
{
if (self)
return self->sup_vtable->su_port_register(self, root, wait,
callback, arg, priority);
errno = EINVAL;
return -1;
}
static inline
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)
{
if (self)
return self->sup_vtable->
su_port_unregister(self, root, wait, callback, arg);
errno = EINVAL;
return -1;
}
static inline
int su_port_deregister(su_port_t *self, int i)
{
if (self)
return self->sup_vtable->
su_port_deregister(self, i);
errno = EINVAL;
return -1;
}
static inline
int su_port_unregister_all(su_port_t *self,
su_root_t *root)
{
if (self)
return self->sup_vtable->
su_port_unregister_all(self, root);
errno = EINVAL;
return -1;
}
static inline
int su_port_eventmask(su_port_t *self, int index, int socket, int events)
{
if (self)
return self->sup_vtable->
su_port_eventmask(self, index, socket, events);
assert(self);
errno = EINVAL;
return -1;
}
static inline
void su_port_run(su_port_t *self)
{
if (self)
self->sup_vtable->su_port_run(self);
}
static inline
void su_port_break(su_port_t *self)
{
if (self)
self->sup_vtable->su_port_break(self);
}
static inline
su_duration_t su_port_step(su_port_t *self, su_duration_t tout)
{
if (self)
return self->sup_vtable->su_port_step(self, tout);
errno = EINVAL;
return (su_duration_t)-1;
}
static inline
int su_port_own_thread(su_port_t const *self)
{
return self == NULL || self->sup_vtable->su_port_own_thread(self);
}
static inline
int su_port_add_prepoll(su_port_t *self,
su_root_t *root,
su_prepoll_f *prepoll,
su_prepoll_magic_t *magic)
{
if (self)
return self->sup_vtable->
su_port_add_prepoll(self, root, prepoll, magic);
errno = EINVAL;
return -1;
}
static inline
int su_port_remove_prepoll(su_port_t *self,
su_root_t *root)
{
if (self)
return self->sup_vtable->su_port_remove_prepoll(self, root);
errno = EINVAL;
return -1;
}
static inline
su_timer_t **su_port_timers(su_port_t *self)
{
if (self)
return self->sup_vtable->su_port_timers(self);
errno = EINVAL;
return NULL;
}
static inline
int su_port_multishot(su_port_t *self, int multishot)
{
if (self)
return self->sup_vtable->su_port_multishot(self, multishot);
assert(self);
errno = EINVAL;
return -1;
}
static inline
int su_port_threadsafe(su_port_t *self)
{
if (self)
return self->sup_vtable->su_port_threadsafe(self);
assert(self);
errno = EINVAL;
return -1;
}
#endif
SOFIA_END_DECLS
#endif /* SU_PORT_H */