コード例 #1
0
ファイル: server.c プロジェクト: tidatida/lacenet
static void on_socket_connect (lw_server server, lw_server_client client)
{
   lnserver ctx = lw_server_tag (server);

   lnserver_client client_ctx = lnserver_client_new (ctx, client);

   if (!client_ctx)
   {
      /* failed to allocate client context */

      lw_stream_close (client, lw_true);
      return;
   }

   lw_stream_set_tag (client, client_ctx);
}
コード例 #2
0
ファイル: fdstream.c プロジェクト: devlato/lacewing
static void read_ready (void * tag)
{
   lw_fdstream ctx = tag;

   if (ctx->flags & lwp_fdstream_flag_reading)
      return;

   ctx->flags |= lwp_fdstream_flag_reading;

   lwp_retain (ctx, "fdstream read_ready");

   /* TODO : Use a buffer on the heap instead? */

   char buffer [lwp_default_buffer_size];

   lw_bool close_stream = lw_false;

   while (ctx->reading_size == -1 || ctx->reading_size > 0)
   {
      if (ctx->fd == -1)
         break;

      size_t to_read = sizeof (buffer);

      if (ctx->reading_size != -1 && to_read > ctx->reading_size)
         to_read = ctx->reading_size;

      int bytes = read (ctx->fd, buffer, to_read);

      if (bytes == 0)
      {
         close_stream = lw_true;
         break;
      }

      if (bytes == -1)
      {
         if (errno == EAGAIN)
            break;

         close_stream = lw_true;
         break;
      }

      if (ctx->reading_size != -1)
      {
         if (bytes > ctx->reading_size)
            ctx->reading_size = 0;
         else
            ctx->reading_size -= bytes;
      }

      lw_stream_data ((lw_stream) ctx, buffer, bytes);

      /* Calling Data or Close may result in destruction of the Stream -
       * see FDStream destructor.
       */

      if (! (ctx->flags & lwp_fdstream_flag_reading))
         break;
   }

   ctx->flags &= ~ lwp_fdstream_flag_reading;

   if (lwp_release (ctx, "fdstream read_ready") || ctx->stream.flags & lwp_stream_flag_dead)
      return;

   if (close_stream)
      lw_stream_close ((lw_stream) ctx, lw_true);
}
コード例 #3
0
ファイル: fdstream.c プロジェクト: devlato/lacewing
void lw_fdstream_set_fd (lw_fdstream ctx, lw_fd fd, lw_pump_watch watch,
                         lw_bool auto_close)
{
   if (ctx->watch)
   {
      lw_pump_remove (lw_stream_pump ((lw_stream) ctx), ctx->watch);
      ctx->watch = 0;
   }

   if ( (ctx->flags & lwp_fdstream_flag_autoclose) && ctx->fd != -1)
      lw_stream_close ((lw_stream) ctx, lw_true);

   ctx->fd = fd;

   if (auto_close)
      ctx->flags |= lwp_fdstream_flag_autoclose;
   else
      ctx->flags &= ~ lwp_fdstream_flag_autoclose;

   if (ctx->fd == -1)
      return;

   fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) | O_NONBLOCK);

   #if HAVE_DECL_SO_NOSIGPIPE
   {  int b = 1;
      setsockopt (fd, SOL_SOCKET, SO_NOSIGPIPE, (char *) &b, sizeof (b));
   }
   #endif

   {  int b = (ctx->flags & lwp_fdstream_flag_nagle) ? 0 : 1;
      setsockopt (fd, SOL_SOCKET, TCP_NODELAY, (char *) &b, sizeof (b));
   }

   struct stat stat;
   fstat (fd, &stat);

   if (S_ISSOCK (stat.st_mode))
   {
      ctx->flags |= lwp_fdstream_flag_is_socket;
   }
   else
   {
      ctx->flags &= ~ lwp_fdstream_flag_is_socket;

      if ((ctx->size = stat.st_size) > 0)
         return;

      /* Not a socket, and size is 0.  Is it really just an empty file? */

      if (S_ISREG (stat.st_mode))
         return;
   }

   /* Assuming this is something we can watch for readiness. */

   ctx->size = -1;

   lw_pump pump = lw_stream_pump ((lw_stream) ctx);

   if (watch)
   {
      /* Given an existing pump watch - change it to use our callbacks */

      ctx->watch = watch;

      lw_pump_update_callbacks (pump, ctx->watch, ctx,
            read_ready, write_ready, lw_true);
   }
   else
   {
      ctx->watch = lw_pump_add (pump, fd, ctx, read_ready,
            write_ready, lw_true);
   }
}