Exemplo n.º 1
0
static FsMsnPollFD *
add_pollfd_locked (FsMsnConnection *self, int fd, PollFdCallback callback,
    gboolean read, gboolean write, gboolean server)
{
  FsMsnPollFD *pollfd = g_slice_new0 (FsMsnPollFD);
  gst_poll_fd_init (&pollfd->pollfd);
  pollfd->pollfd.fd = fd;
  pollfd->server = server;
  pollfd->want_read = read;
  pollfd->want_write = write;
  pollfd->status = FS_MSN_STATUS_AUTH;

  gst_poll_add_fd (self->poll, &pollfd->pollfd);

  gst_poll_fd_ctl_read (self->poll, &pollfd->pollfd, read);
  gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, write);
  pollfd->callback = callback;

  GST_DEBUG ("ADD_POLLFD %p (%p) - error %d, close %d, read %d-%d, write %d-%d",
      self->pollfds, pollfd,
      gst_poll_fd_has_error (self->poll, &pollfd->pollfd),
      gst_poll_fd_has_closed (self->poll, &pollfd->pollfd),
      pollfd->want_read,
      gst_poll_fd_can_read (self->poll, &pollfd->pollfd),
      pollfd->want_write,
      gst_poll_fd_can_write (self->poll, &pollfd->pollfd));

  g_ptr_array_add (self->pollfds, pollfd);
  gst_poll_restart (self->poll);
  return pollfd;
}
Exemplo n.º 2
0
static gboolean
exchange_packets (GstPluginLoader * l)
{
  gint res;

  /* Wait for activity on our FDs */
  do {
    do {
      res = gst_poll_wait (l->fdset, GST_SECOND);
    } while (res == -1 && (errno == EINTR || errno == EAGAIN));

    if (res < 0)
      return FALSE;

    GST_LOG ("Poll res = %d. %d bytes pending for write", res,
        l->tx_buf_write - l->tx_buf_read);

    if (!l->rx_done) {
      if (gst_poll_fd_has_error (l->fdset, &l->fd_r) ||
          gst_poll_fd_has_closed (l->fdset, &l->fd_r)) {
        GST_LOG ("read fd %d closed/errored", l->fd_r.fd);
        goto fail_and_cleanup;
      }

      if (gst_poll_fd_can_read (l->fdset, &l->fd_r)) {
        if (!read_one (l))
          goto fail_and_cleanup;
      }
    }

    if (l->tx_buf_read < l->tx_buf_write) {
      if (gst_poll_fd_has_error (l->fdset, &l->fd_w) ||
          gst_poll_fd_has_closed (l->fdset, &l->fd_r)) {
        GST_ERROR ("write fd %d closed/errored", l->fd_w.fd);
        goto fail_and_cleanup;
      }
      if (gst_poll_fd_can_write (l->fdset, &l->fd_w)) {
        if (!write_one (l))
          goto fail_and_cleanup;
      }
    }
  } while (l->tx_buf_read < l->tx_buf_write);

  return TRUE;
fail_and_cleanup:
  plugin_loader_cleanup_child (l);
  return FALSE;
}
Exemplo n.º 3
0
static gpointer
connection_polling_thread (gpointer data)
{
  FsMsnConnection *self = data;
  gint ret;
  GstClockTime timeout;
  GstPoll * poll;

  FS_MSN_CONNECTION_LOCK(self);
  timeout = self->poll_timeout;
  poll = self->poll;
  GST_DEBUG ("poll waiting %d", self->pollfds->len);
  FS_MSN_CONNECTION_UNLOCK(self);

  while ((ret = gst_poll_wait (poll, timeout)) >= 0)
  {
    GST_DEBUG ("gst_poll_wait returned : %d", ret);
    FS_MSN_CONNECTION_LOCK(self);
    if (ret > 0)
    {
      gint i;

      for (i = 0; i < self->pollfds->len; i++)
      {
        FsMsnPollFD *pollfd = NULL;

        pollfd = g_ptr_array_index(self->pollfds, i);

        GST_DEBUG ("ret %d - i = %d, len = %d", ret, i, self->pollfds->len);

        GST_DEBUG ("%p - error %d, close %d, read %d-%d, write %d-%d",
            pollfd,
            gst_poll_fd_has_error (poll, &pollfd->pollfd),
            gst_poll_fd_has_closed (poll, &pollfd->pollfd),
            pollfd->want_read,
            gst_poll_fd_can_read (poll, &pollfd->pollfd),
            pollfd->want_write,
            gst_poll_fd_can_write (poll, &pollfd->pollfd));

        if (gst_poll_fd_has_error (poll, &pollfd->pollfd) ||
            gst_poll_fd_has_closed (poll, &pollfd->pollfd))
        {
          pollfd->callback (self, pollfd);
          shutdown_fd_locked (self, pollfd, TRUE);
          i--;
          continue;
        }
        if ((pollfd->want_read &&
                gst_poll_fd_can_read (poll, &pollfd->pollfd)) ||
            (pollfd->want_write &&
                gst_poll_fd_can_write (poll, &pollfd->pollfd)))
        {
          pollfd->callback (self, pollfd);
        }

      }
    }
    timeout = self->poll_timeout;
    FS_MSN_CONNECTION_UNLOCK(self);
  }

  return NULL;
}
Exemplo n.º 4
0
static void
connection_cb (FsMsnConnection *self, FsMsnPollFD *pollfd)
{
  gboolean success = FALSE;

  GST_DEBUG ("handler called on fd:%d server: %d status:%d r:%d w:%d",
      pollfd->pollfd.fd,
      pollfd->server, pollfd->status,
      gst_poll_fd_can_read (self->poll, &pollfd->pollfd),
      gst_poll_fd_can_write (self->poll, &pollfd->pollfd));

  if (gst_poll_fd_has_error (self->poll, &pollfd->pollfd) ||
      gst_poll_fd_has_closed (self->poll, &pollfd->pollfd))
  {
    GST_WARNING ("connecton closed or error (error: %d closed: %d)",
        gst_poll_fd_has_error (self->poll, &pollfd->pollfd),
        gst_poll_fd_has_closed (self->poll, &pollfd->pollfd));
    goto error;
  }

  if (gst_poll_fd_can_read (self->poll, &pollfd->pollfd))
  {
    switch (pollfd->status)
    {
      case FS_MSN_STATUS_AUTH:
        if (pollfd->server)
        {
          gchar str[35] = {0};
          gchar check[35] = {0};

          if (recv (pollfd->pollfd.fd, str, 34, 0) == 34)
          {
            GST_DEBUG ("Got %s, checking if it's auth", str);
            FS_MSN_CONNECTION_LOCK(self);
            snprintf(check, 35, "recipientid=%s&sessionid=%d\r\n\r\n",
                self->local_recipient_id, self->session_id);
            FS_MSN_CONNECTION_UNLOCK(self);
            if (strncmp (str, check, 35) == 0)
            {
              GST_DEBUG ("Authentication successful");
              pollfd->status = FS_MSN_STATUS_CONNECTED;
              pollfd->want_write = TRUE;
              gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, TRUE);
            }
            else
            {
              GST_WARNING ("Authentication failed check=%s", check);
              goto error;
            }
          }
          else
          {
            gchar error_str[256];
            strerror_r (errno, error_str, 256);
            GST_WARNING ("auth: %s", error_str);
            goto error;
          }

        } else {
          GST_ERROR ("shouldn't receive data when client on AUTH state");
          goto error;
        }
        break;
      case FS_MSN_STATUS_CONNECTED:
        if (!pollfd->server)
        {
          gchar str[14] = {0};
          ssize_t size;

          size = recv (pollfd->pollfd.fd, str, 13, MSG_PEEK);
          if (size > 0)
          {
            GST_DEBUG ("Got %s, checking if it's connected", str);
            if (size == 13 && strcmp (str, "connected\r\n\r\n") == 0)
            {
              GST_DEBUG ("connection successful");
              recv (pollfd->pollfd.fd, str, 13, 0);
              pollfd->status = FS_MSN_STATUS_CONNECTED2;
              pollfd->want_write = TRUE;
              gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, TRUE);
            }
            else if (!self->producer)
            {
              GST_DEBUG ("connection successful");
              pollfd->status = FS_MSN_STATUS_SEND_RECEIVE;
              success = TRUE;
            }
            else
            {
              GST_WARNING ("connected failed");
              goto error;
            }
          }
          else
          {
            gchar error_str[256];
            strerror_r (errno, error_str, 256);
            GST_WARNING ("recv: %s", error_str);
            goto error;
          }
        } else {
          GST_ERROR ("shouldn't receive data when server on CONNECTED state");
          goto error;
        }
        break;
      case FS_MSN_STATUS_CONNECTED2:
        if (pollfd->server)
        {
          gchar str[14] = {0};
          ssize_t size;

          size = recv (pollfd->pollfd.fd, str, 13, MSG_PEEK);
          if (size > 0)
          {
            GST_DEBUG ("Got %s, checking if it's connected", str);
            if (size == 13 && strcmp (str, "connected\r\n\r\n") == 0)
            {
              GST_DEBUG ("connection successful");
              recv (pollfd->pollfd.fd, str, 13, 0);
              pollfd->status = FS_MSN_STATUS_SEND_RECEIVE;
              success = TRUE;
            }
            else if (!self->producer)
            {
              GST_DEBUG ("connection successful");
              pollfd->status = FS_MSN_STATUS_SEND_RECEIVE;
              success = TRUE;
            }
            else
            {
              GST_WARNING ("connected failed");
              goto error;
            }
          }
          else
          {
            gchar error_str[256];
            strerror_r (errno, error_str, 256);
            GST_WARNING ("recv: %s", error_str);
            goto error;
          }

        } else {
          GST_ERROR ("shouldn't receive data when client on CONNECTED2 state");
          goto error;
        }
        break;
      default:
        GST_ERROR ("Invalid status %d", pollfd->status);
        goto error;
        break;

    }
  }
  else if (gst_poll_fd_can_write (self->poll, &pollfd->pollfd))
  {
    pollfd->want_write = FALSE;
    gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, FALSE);
    switch (pollfd->status)
    {
      case FS_MSN_STATUS_AUTH:
        if (!pollfd->server)
        {
          gchar *str;
          FS_MSN_CONNECTION_LOCK(self);
          str = g_strdup_printf("recipientid=%s&sessionid=%d\r\n\r\n",
              self->remote_recipient_id, self->session_id);
          FS_MSN_CONNECTION_UNLOCK(self);
          if (send(pollfd->pollfd.fd, str, strlen (str), 0) != -1)
          {
            GST_DEBUG ("Sent %s", str);
            pollfd->status = FS_MSN_STATUS_CONNECTED;
            g_free (str);
          }
          else
          {
            gchar error_str[256];
            strerror_r (errno, error_str, 256);
            GST_WARNING ("auth send: %s", error_str);
            g_free (str);
            goto error;
          }

        }
        break;
      case FS_MSN_STATUS_CONNECTED:
        if (pollfd->server)
        {

          if (send(pollfd->pollfd.fd, "connected\r\n\r\n", 13, 0) != -1)
          {
            GST_DEBUG ("sent connected");
            if (self->producer)
            {
              pollfd->status = FS_MSN_STATUS_SEND_RECEIVE;
              success = TRUE;
            }
            else
            {
              pollfd->status = FS_MSN_STATUS_CONNECTED2;
            }
          }
          else
          {
            gchar error_str[256];
            strerror_r (errno, error_str, 256);
            GST_WARNING ("sending connected: %s", error_str);
            goto error;
          }
        } else {
          GST_DEBUG ("shouldn't receive data when server on CONNECTED state");
          goto error;
        }
        break;
      case FS_MSN_STATUS_CONNECTED2:
        if (!pollfd->server)
        {

          if (send(pollfd->pollfd.fd, "connected\r\n\r\n", 13, 0) != -1)
          {
            GST_DEBUG ("sent connected");
            pollfd->status = FS_MSN_STATUS_SEND_RECEIVE;
            success = TRUE;
          }
          else
          {
            gchar error_str[256];
            strerror_r (errno, error_str, 256);
            GST_WARNING ("sending connected: %s", error_str);
            goto error;
          }
        } else {
          GST_ERROR ("shouldn't receive data when client on CONNECTED2 state");
          goto error;
        }
        break;
      default:
        GST_ERROR ("Invalid status %d", pollfd->status);
        goto error;
        break;
    }
  }

  if (success) {
    // success! we need to shutdown/close all other channels
    shutdown_fd (self, pollfd, FALSE);

    g_signal_emit (self, signals[SIGNAL_CONNECTED], 0, pollfd->pollfd.fd);

    pollfd->want_read = FALSE;
    pollfd->want_write = FALSE;
    gst_poll_fd_ctl_read (self->poll, &pollfd->pollfd, FALSE);
    gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, FALSE);
  }

  return;
 error:
  /* Error */
  GST_WARNING ("Got error from fd %d, closing", pollfd->pollfd.fd);
  shutdown_fd (self, pollfd, TRUE);

  FS_MSN_CONNECTION_LOCK (self);
  success = (self->pollfds->len > 1);
  FS_MSN_CONNECTION_UNLOCK (self);

  if (!success)
    g_signal_emit (self, signals[SIGNAL_CONNECTION_FAILED], 0);

  return;
}
Exemplo n.º 5
0
static void
mess_some_more (void)
{
  GList *walk;
  gint random;
  gint removed = 0;

  g_mutex_lock (fdlock);

  for (walk = fds; walk;) {
    GstPollFD *fd = (GstPollFD *) walk->data;

    walk = g_list_next (walk);

    random = (gint) (10.0 * rand () / (RAND_MAX + 1.0));
    switch (random) {
      case 0:
      {
        /*
           GstPollFD *newfd = g_new0 (GstPollFD, 1);

           gst_poll_add_fd (set, newfd);
           fds = g_list_prepend (fds, newfd);
         */
        break;
      }
      case 1:
        if ((gint) (10.0 * rand () / (RAND_MAX + 1.0)) < 2) {
          gst_poll_remove_fd (set, fd);
          fds = g_list_remove (fds, fd);
          g_free (fd);
          removed++;
        }
        break;

      case 2:
        gst_poll_fd_ctl_write (set, fd, TRUE);
        break;
      case 3:
        gst_poll_fd_ctl_write (set, fd, FALSE);
        break;
      case 4:
        gst_poll_fd_ctl_read (set, fd, TRUE);
        break;
      case 5:
        gst_poll_fd_ctl_read (set, fd, FALSE);
        break;

      case 6:
        gst_poll_fd_has_closed (set, fd);
        break;
      case 7:
        gst_poll_fd_has_error (set, fd);
        break;
      case 8:
        gst_poll_fd_can_read (set, fd);
        break;
      case 9:
        gst_poll_fd_can_write (set, fd);
        break;
      default:
        g_assert_not_reached ();
        break;
    }
  }
  if (g_list_length (fds) < 900) {
    random = removed + (gint) (2.0 * rand () / (RAND_MAX + 1.0));
    while (random) {
      GstPollFD *newfd = g_new0 (GstPollFD, 1);

      gst_poll_add_fd (set, newfd);
      fds = g_list_prepend (fds, newfd);
      random--;
    }
  }

  g_mutex_unlock (fdlock);
}