Logo Search packages:      
Sourcecode: sofia-sip version File versions

TPORT_DLL int tport_tqsend ( tport_t *  self,
msg_t msg,
msg_t next,
tag_type_t  tag,
tag_value_t  value,
  ... 
)

Send a queued message (and queue another, if required).

Send a queued message (and queue another, if required).

The function tport_tqsend() sends a message to the transport.

Deprecated:
Alternative interface will be provided in near future.

Definition at line 3541 of file tport.c.

References msg_addrinfo(), msg_destroy(), msg_ref_create(), msg_set_errno(), ta_args, ta_end, ta_start, TAG_END, tl_gets(), TP_AI_CLOSE, TP_AI_SHUTDOWN, and tport_tqsend().

Referenced by server_reply(), and tport_tqsend().

{
  unsigned short qhead;
  ta_list ta;
  int reuse, sdwn_after, close_after;
  unsigned short N;
  su_addrinfo_t *ai;

  if (self == NULL)
    return -1;

  qhead = self->tp_qhead;
  N = self->tp_params->tpp_qsize;
  reuse = self->tp_reusable;
  sdwn_after = 0;
  close_after = 0;

  ta_start(ta, tag, value);

  tl_gets(ta_args(ta),
        TPTAG_REUSE_REF(reuse),
        TPTAG_SDWN_AFTER_REF(sdwn_after),
        TPTAG_CLOSE_AFTER_REF(close_after),
        TAG_END());

  ta_end(ta);

  /* If "next", make sure we can queue it */
  if (next && self->tp_queue[qhead == 0 ? N - 1 : qhead - 1]) {
    msg_set_errno(next, ENOBUFS);
    return -1;
  }

  /* Prepare message for sending - i.e., encode it */
  if (msg_prepare(msg) < 0) {
    msg_set_errno(msg, errno);
    return -1;
  }

  tport_peer_address(self, msg);  /* Set addrinfo */
  if (next == NULL) {
    ai = msg_addrinfo(msg);

    if (sdwn_after)
      ai->ai_flags |= TP_AI_SHUTDOWN;
    if (close_after)
      ai->ai_flags |= TP_AI_CLOSE;

    if (self->tp_queue[qhead] == msg)
      tport_send_queue(self);
    return 0;
  }

  ai = msg_addrinfo(next);

  if (sdwn_after)
    ai->ai_flags |= TP_AI_SHUTDOWN;
  if (close_after)
    ai->ai_flags |= TP_AI_CLOSE;

  if (self->tp_queue[qhead] == msg) {
    /* XXX - what about errors? */
    tport_send_msg(self, msg, self->tp_name, NULL);
    if (!self->tp_unsent) {
      msg_destroy(self->tp_queue[qhead]);
      if ((self->tp_queue[qhead] = msg_ref_create(next)))
      msg_unprepare(next);
      return 0; 
    }
  }

  while (self->tp_queue[qhead] && self->tp_queue[qhead] != msg) {
    qhead = (qhead + 1) % N;
    if (qhead == self->tp_qhead)
      break;
  }

  if (self->tp_queue[qhead] != msg) {
    msg_set_errno(next, EINVAL);
    return -1;
  }

  msg = msg_ref_create(next);

  do {
    qhead = (qhead + 1) % N;
    next = self->tp_queue[qhead]; self->tp_queue[qhead] = msg; msg = next;
    /* Above we made sure that there is an empty slot */
    assert(!next || qhead != self->tp_qhead); 
  } while (next);

  return 0;
}


Generated by  Doxygen 1.6.0   Back to index