⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 su_root.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 2 页
字号:
 *  The function su_root_deregister() deregisters a su_wait_t object. The *  wait object, a callback function and a argument are removed from the *  root object. The wait object is destroyed. * * @param self      pointer to root object * @param index     registration index * * @return Index of the wait object, or -1 upon an error. */int su_root_deregister(su_root_t *self, int index){  if (!self)    return (void)(errno = EFAULT), -1;  if (index == 0 || index == -1)    return (void)(errno = EINVAL), -1;  assert(self->sur_port);  return su_port_deregister(self->sur_port, index);}/** Set mask for a registered event. * * The function su_root_eventmask() sets the mask describing events that can * signal the registered callback. * * @param self   pointer to root object * @param index  registration index * @param socket socket * @param events new event mask * * @retval 0 when successful, * @retval -1 upon an error. */int su_root_eventmask(su_root_t *self, int index, int socket, int events){  if (!self)    return (void)(errno = EFAULT), -1;  if (index == 0 || index == -1)    return (void)(errno = EINVAL), -1;  assert(self->sur_port);  return su_port_eventmask(self->sur_port, index, socket, events);}/** Set multishot mode. * * The function su_root_multishot() enables, disables or queries the * multishot mode for the root. The multishot mode determines how the events * are scheduled by root. If multishot mode is enabled, root serves all the * sockets that have received network events. If it is disables, only first * socket event is served. * * @param self      pointer to root object * @param multishot multishot mode (0 => disables, 1 => enables, -1 => query) *  * @retval 0 multishot mode is disabled * @retval 1 multishot mode is enabled * @retval -1 an error occurred */int su_root_multishot(su_root_t *self, int multishot){  if (!self)    return (void)(errno = EFAULT), -1;  assert(self->sur_port);  return su_port_multishot(self->sur_port, multishot);}/** Run event and message loop. * * The function su_root_run() runs the root main loop. The root loop waits * for wait objects and the timers associated with the root object. When any * wait object is signaled or timer is expired, it invokes the callbacks, * and returns waiting. * * This function returns when su_root_break() is called from a callback. * * @param self      pointer to root object * */void su_root_run(su_root_t *self){  if (!self)    return /* (void)(errno = EFAULT), -1 */;  assert(self->sur_port);  /* return */ su_port_run(self->sur_port);}/** Terminate event loop. * *   The function su_root_break() is used to terminate execution of *   su_root_run(). It can be called from a callback function. * * @param self      pointer to root object */void su_root_break(su_root_t *self){  if (!self)    return /* (void)(errno = EFAULT), -1 */;  assert(self->sur_port);  /* return */ su_port_break(self->sur_port);}/** Process events, timers and messages. * *   The function su_root_step() waits for wait objects and the timers *   associated with the root object.  When any wait object is signaled or *   timer is expired, it invokes the callbacks. * *   This function returns when a callback has been invoked or tout *   milliseconds is elapsed. * * @param self      pointer to root object * @param tout      timeout in milliseconds * * @return Milliseconds to the next invocation of timer * @retval SU_WAIT_FOREVER if there are no active timers or if there was an error */su_duration_t su_root_step(su_root_t *self, su_duration_t tout){  if (self == NULL)    return (void)(errno = EFAULT), SU_WAIT_FOREVER;  assert(self->sur_port);  return su_port_step(self->sur_port, tout);}/**Run event and message loop for given duration. * * The function su_root_sleep() runs event loop for @a duration milliseconds. * The event loop waits for wait objects and the timers associated with the * @a root object.  When any wait object is signaled, timer is expired, or * message is received, it invokes the callbacks and returns waiting. * * @param self      pointer to root object * @param duration  milliseconds to run event loop * * @retval milliseconds until next timer expiration */su_duration_t su_root_sleep(su_root_t *self, su_duration_t duration){  su_duration_t retval, accrued = 0;  su_time_t started;  if (self == NULL)    return (void)(errno = EFAULT), SU_WAIT_FOREVER;  assert(self->sur_port);  started = su_now();  do {    retval = su_port_step(self->sur_port, duration - accrued);    accrued = su_duration(su_now(), started);  } while (accrued < duration);  return retval;}/** Check wait events in callbacks that take lots of time * * This function does a 0 timeout poll() and runs wait objects * * @param self pointer to root object */int su_root_yield(su_root_t *self){  if (self == NULL)    return (void)(errno = EFAULT), SU_WAIT_FOREVER;  assert(self->sur_port);  return su_port_wait_events(self->sur_port, 0);}/** Get task reference. * * Retrieve the task reference related with the root object. * * @param self      a pointer to a root object * * @return A reference to the task object. */_su_task_r su_root_task(su_root_t const *self){  if (self)    return self->sur_task;  else    return su_task_null;}/** Get parent task reference. * * Retrieve the task reference of the parent task associated with the root * object. * * @param self a pointer to a root object * * @return A reference to the parent task object. */_su_task_r su_root_parent(su_root_t const *self){  if (self)    return self->sur_parent;  else    return su_task_null;}/** Add a pre-poll callback. */int su_root_add_prepoll(su_root_t *root, 			su_prepoll_f *callback, 			su_prepoll_magic_t *magic){  if (root == NULL)    return (void)(errno = EFAULT), -1;  assert(root->sur_port);  return su_port_add_prepoll(root->sur_port, root, callback, magic);}/** Remove a pre-poll callback */int su_root_remove_prepoll(su_root_t *root){  if (root == NULL)    return (void)(errno = EFAULT), -1;  assert(root->sur_port);  return su_port_remove_prepoll(root->sur_port, root);}/** Release the root port for other threads. * * @NEW_1_12_7 */int su_root_release(su_root_t *root){  if (root == NULL || root->sur_port == NULL)    return (void)(errno = EFAULT), -1;  return su_port_release(root->sur_port);}/** Obtain the root port from other thread.  * * @param root pointer to root object * * @retval 0 if successful * @retval -1 upon an error * * @ERRORS * @ERROR EFAULT  * @NEW_1_12_7 */int su_root_obtain(su_root_t *root){  if (root == NULL || root->sur_port == NULL)    return (void)(errno = EFAULT), -1;  return su_port_obtain(root->sur_port);}/**Check if a thread has obtained the root.  * * @param root a pointer to root object * * @retval 2 if current thread has obtained the root * @retval 1 if an another thread  has obtained the root * @retval 0 if no thread has obtained the root * @retval -1 upon an error * * @NEW_1_12_7 */int su_root_has_thread(su_root_t *root){  if (root == NULL || root->sur_port == NULL)    return (void)(errno = EFAULT), -1;  return su_port_has_thread(root->sur_port);}/* ========================================================================= * Messages *//** * Allocate a su message of given size. * * Allocate a su message with given data size.  * * @param  rmsg   handle to the new message (may be uninitialized prior calling) * @param  size   size of the message data * * @retval  0 if successful, * @retval -1 if message allocation fails.   * * @NEW_1_12_8 */int su_msg_new(su_msg_r rmsg, size_t size){  su_msg_t *msg;  size_t total = sizeof(*msg) + (size_t)size;  *rmsg = msg = su_zalloc(NULL, (isize_t)total);  if (!*rmsg)    return -1;  msg->sum_size = total;  return 0;}/** * Allocates a message of given size. * * The function @c su_msg_create() allocates a message with given data size. * If successful, it moves the new message handle to the @c rmsg. * * @param  rmsg   handle to the new message (may be uninitialized prior calling) * @param  to     the recipient task * @param  from   the sender task * @param  wakeup function that is called when message is delivered * @param  size   size of the message data * * @retval  0 if successful, * @retval -1 if message allocation fails.   */int su_msg_create(su_msg_r        rmsg,		  su_task_r const to,		  su_task_r const from,		  su_msg_f        wakeup,		  isize_t         size){  if (su_msg_new(rmsg, (size_t) size) == 0) {    SU_TASK_COPY(rmsg[0]->sum_to, to, su_msg_create);    SU_TASK_COPY(rmsg[0]->sum_from, from, su_msg_create);    rmsg[0]->sum_func = wakeup;    return 0;  }   return -1;}/** Add a delivery report function to a message. *  * The delivery report funcgtion gets called by the sending task after the * message was delivered and the message function was executed. (The * su_root_t message delivery loop calls su_msg_delivery_report()  *  */int su_msg_report(su_msg_r msg,		  su_msg_f report){  if (msg && msg[0] && msg[0]->sum_report == NULL) {    msg[0]->sum_report = report;    return 0;  }  return -1;}/** Add a deinitializer function to a message. * * The deinitializer function is called when the message gets destroyed. It * is called even if the message was never delivered. Note that the thread * destroying the message and calling the deinit function is not necessarily * the same that sent the message nor the original recipient. * * @param rmsg   message reference * @param deinit pointer to deinitializer function * * @NEW_1_12_8 */int su_msg_deinitializer(su_msg_r rmsg,			 su_msg_deinit_function *deinit){  if (rmsg && rmsg[0]) {    rmsg[0]->sum_deinit = deinit;    return 0;  }  return -1;}/** * Allocates a reply message of given size. * * @param reply     handle to the new message (may be uninitialized prior calling) * @param rmsg       the incoming message * @param wakeup    function that is called when message is delivered * @param size      size of the message data * * @retval 0 if successful, * @retval -1 otherwise. */int su_msg_reply(su_msg_r reply, su_msg_cr rmsg,		 su_msg_f wakeup, isize_t size){  su_msg_r rmsg0;  assert(rmsg != reply);  *rmsg0 = *(su_msg_t **) rmsg;  *reply = NULL;  return su_msg_create(reply, su_msg_from(rmsg0), su_msg_to(rmsg0), wakeup, size);}/** Send a delivery report. * * If the sender has attached a delivery report function to message with * su_msg_report(), the message is returned to the message queue of the * sending task. The sending task calls the delivery report function when it * has received the message. */void su_msg_delivery_report(su_msg_r rmsg){  su_task_r swap;  if (!rmsg || !rmsg[0])    return;  if (!rmsg[0]->sum_report) {    su_msg_destroy(rmsg);    return;  }  *swap = *rmsg[0]->sum_from;  *rmsg[0]->sum_from = *rmsg[0]->sum_to;  *rmsg[0]->sum_to = *swap;  rmsg[0]->sum_func = rmsg[0]->sum_report;  rmsg[0]->sum_report = NULL;  su_msg_send(rmsg);}/** Save a message. */void su_msg_save(su_msg_r save, su_msg_r rmsg){  if (save) {    if (rmsg)      save[0] = rmsg[0];    else      save[0] = NULL;  }  if (rmsg)    rmsg[0] = NULL;}/** * Destroys an unsent message. * * @param rmsg       message handle. */void su_msg_destroy(su_msg_r rmsg){  su_msg_t *msg;  assert(rmsg);  msg = rmsg[0], rmsg[0] = NULL;  if (msg) {    SU_TASK_ZAP(msg->sum_to, su_msg_destroy);    SU_TASK_ZAP(msg->sum_from, su_msg_destroy);    if (msg->sum_deinit)      msg->sum_deinit(msg->sum_data);    su_free(NULL, msg);  }}/** Gets a pointer to the message data area.  * * The function @c su_msg_data() returns a pointer to the message data * area. If @c rmsg contains a @c NULL handle, or message size is 0, @c NULL * pointer is returned. * * @param rmsg       message handle * * @return A pointer to the message data area is returned.   */su_msg_arg_t *su_msg_data(su_msg_cr rmsg){  if (rmsg[0] && rmsg[0]->sum_size > sizeof(su_msg_t))    return rmsg[0]->sum_data;  else    return NULL;}/** Get size of message data area. */isize_t su_msg_size(su_msg_cr rmsg){  return rmsg[0] ? rmsg[0]->sum_size - sizeof(su_msg_t) : 0;}/** Get sending task. * * Returns the task handle belonging to the sender of the message. * * If the message handle contains NULL the function @c su_msg_from * returns NULL. * * @param rmsg       message handle * * @return The task handle of the sender is returned.   */_su_task_r su_msg_from(su_msg_cr rmsg){  return rmsg[0] ? rmsg[0]->sum_from : NULL;}/** Get destination task. * * The function @c su_msg_from returns the task handle belonging to the * recipient of the message. * * If the message handle contains NULL the function @c su_msg_to * returns NULL. * * @param rmsg       message handle * * @return The task handle of the recipient is returned.   */_su_task_r su_msg_to(su_msg_cr rmsg){  return rmsg[0] ? rmsg[0]->sum_to : NULL;}/** Remove references to 'from' and 'to' tasks from a message.  * * @param rmsg       message handle */void su_msg_remove_refs(su_msg_cr rmsg){  if (rmsg[0]) {    su_task_deinit(rmsg[0]->sum_to);    su_task_deinit(rmsg[0]->sum_from);  }}/**Send a message.  * * The function @c su_msg_send() sends the message. The message is added to * the recipients message queue, and recipient is waken up. The caller may * not alter the message or the data associated with it after the message * has been sent. * * @param rmsg message handle * * @retval 0 if signal was sent successfully or handle was @c NULL, * @retval -1 otherwise. */int su_msg_send(su_msg_r rmsg){  assert(rmsg);  if (rmsg[0]) {    su_msg_t *msg = rmsg[0];    if (msg->sum_to->sut_port)       return su_port_send(msg->sum_to->sut_port, rmsg);    su_msg_destroy(rmsg);    errno = EINVAL;    return -1;  }  return 0;		}/** Send message to the @a to_task and mark @a from_task as sender. * * @NEW_1_12_8 */SOFIAPUBFUN int su_msg_send_to(su_msg_r rmsg,			       su_task_r const to_task,			       su_msg_f wakeup){  assert(rmsg); assert(to_task);  if (rmsg[0]) {    su_msg_t *msg = rmsg[0];    if (wakeup)      msg->sum_func = wakeup;    if (msg->sum_to->sut_port && 	msg->sum_to->sut_port != to_task->sut_port) {      SU_TASK_ZAP(msg->sum_to, "su_msg_send_to");     }    if (to_task->sut_port != NULL) {      msg->sum_to->sut_port = NULL;      msg->sum_to->sut_root = to_task->sut_root;      return su_port_send(to_task->sut_port, rmsg);    }    su_msg_destroy(rmsg);    errno = EINVAL;    return -1;  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -