예제 #1
0
static void
handle_fd_connecting (DskFileDescriptor   fd,
                      unsigned            events,
                      void               *callback_data)
{
  int err = dsk_errno_from_fd (fd);
  DskClientStream *stream = callback_data;
  DSK_UNUSED (events);
  if (err == 0)
    {
      stream->is_connecting = DSK_FALSE;
      stream->is_connected = DSK_TRUE;
      handle_fd_connected (stream);             /* sets the watch on the fd */
      return;
    }

  if (err != EINTR && err != EAGAIN)
    {
      dsk_octet_stream_set_last_error (&stream->base_instance,
                                       "error finishing connection to %s: %s",
                                       stream->name, strerror (err));
      dsk_dispatch_close_fd (dsk_dispatch_default (), stream->fd);
      stream->fd = -1;
      stream->is_connecting = DSK_FALSE;
      maybe_set_autoreconnect_timer (stream);
      return;
    }

  /* wait for another notification */
  return;
}
예제 #2
0
파일: dsk-main.c 프로젝트: davebenson/dsk
DskDispatchSignal*dsk_main_add_signal      (int                 signal_number,
                                            DskSignalHandler    func,
                                            void               *func_data)
{
  return dsk_dispatch_add_signal (dsk_dispatch_default (),
                                  signal_number, func, func_data);
}
예제 #3
0
파일: dsk-main.c 프로젝트: davebenson/dsk
DskDispatchChild *dsk_main_add_child       (int                 process_id,
                                            DskChildHandler     func,
                                            void               *func_data)
{
  return dsk_dispatch_add_child (dsk_dispatch_default (),
                                 process_id, func, func_data);
}
예제 #4
0
파일: server.c 프로젝트: davebenson/snipez
/* --- Creating a user in a game --- */
static User *
create_user (Game *game, const char *name, unsigned width, unsigned height)
{
  User *user = dsk_malloc (sizeof (User));
  Cell *cell;

  user->name = dsk_strdup (name);
  user->base.type = OBJECT_TYPE_USER;
  user->base.game = game;

  /* pick random unoccupied position */
  teleport_object (&user->base);

  cell = game->cells
       + (user->base.x / CELL_SIZE)
       + (user->base.y / CELL_SIZE) * game->universe_width;

  add_object_to_game_list (&user->base);
  add_object_to_cell_list (&user->base);

  user->bullet_block = 0;
  user->bullet_x = user->bullet_y = 0;

  user->width = width;
  user->height = height;

  user->dead_count = 0;

  user->last_seen_time = dsk_dispatch_default ()->last_dispatch_secs;
  user->move_x = user->move_y = 0;
  user->last_update = (unsigned)(-1);
  return user;
}
예제 #5
0
파일: dsk-main.c 프로젝트: davebenson/dsk
DskDispatchTimer *dsk_main_add_timer_millis(unsigned            milliseconds,
                                            DskTimerFunc        func,
                                            void               *func_data)
{
  return dsk_dispatch_add_timer_millis (dsk_dispatch_default (),
                                        milliseconds, func, func_data);
}
예제 #6
0
파일: dsk-main.c 프로젝트: davebenson/dsk
DskDispatchTimer *dsk_main_add_timer       (unsigned            timeout_secs,
                                            unsigned            timeout_usecs,
                                            DskTimerFunc        func,
                                            void               *func_data)
{
  return dsk_dispatch_add_timer (dsk_dispatch_default (),
                                 timeout_secs, timeout_usecs, func, func_data);
}
예제 #7
0
파일: dsk-main.c 프로젝트: davebenson/dsk
int
dsk_main_run             (void)
{
  DskDispatch *d = dsk_dispatch_default ();
  while (main_exit_status < 0)
    dsk_dispatch_run (d);
  return main_exit_status;
}
예제 #8
0
파일: dsk-main.c 프로젝트: davebenson/dsk
void              dsk_main_watch_fd        (DskFileDescriptor   fd,
                                            unsigned            events,
                                            DskFDFunc           callback,
                                            void               *callback_data)
{
  dsk_assert (fd >= 0);
  dsk_dispatch_watch_fd (dsk_dispatch_default (),
                         fd, events, callback, callback_data);
}
예제 #9
0
static void
maybe_set_autoreconnect_timer (DskClientStream *stream)
{
  dsk_assert (stream->reconnect_timer == NULL);
  if (stream->reconnect_time_ms >= 0)
    stream->reconnect_timer
      = dsk_dispatch_add_timer_millis (dsk_dispatch_default (),
                                       stream->reconnect_time_ms,
                                       handle_reconnect_timer_expired,
                                       stream);
}
예제 #10
0
static void
handle_fd_connected (DskClientStream *stream)
{
  stream_do_watch_fd (stream);
  dsk_assert (stream->idle_disconnect_timer == NULL);
  if (stream->idle_disconnect_time_ms >= 0)
    stream->idle_disconnect_timer = dsk_dispatch_add_timer_millis (dsk_dispatch_default (),
                                                                   stream->idle_disconnect_time_ms,
                                                                   handle_idle_too_long,
                                                                   stream);
}
예제 #11
0
/* use -1 to disable these timeouts */
void
dsk_client_stream_set_reconnect_time (DskClientStream *client,
                                      int              millis)
{
  /* short-circuit no-op cases */
  if (millis < 0)
    {
      if (client->reconnect_time_ms == -1)
        return;
      millis = -1;
    }
  else if (client->reconnect_time_ms == millis)
    return;

  /* if we have a valid file-descriptor or we are resolving the name,
     there then the reconnect_time_ms is not currently relevant:
     set it and go */
  if (client->fd != -1 || client->is_resolving_name)
    {
      client->reconnect_time_ms = millis;
      return;
    }

  if (millis == -1)
    {
      /* handle timer removal */
      if (client->reconnect_timer)
        {
          dsk_dispatch_remove_timer (client->reconnect_timer);
          client->reconnect_timer = NULL;
        }
      else
        dsk_warn_if_reached ("no reconnect timer?");
    }
  else
    {
      if (client->reconnect_time_ms >= 0)
        dsk_dispatch_remove_timer (client->reconnect_timer);
      else
        dsk_assert (client->reconnect_timer == NULL);
      client->reconnect_time_ms = millis;

      /* TODO: subtract elapsed time from last disconnect / failed to connect */

      client->reconnect_timer
        = dsk_dispatch_add_timer_millis (dsk_dispatch_default (),
                                         millis,
                                         handle_reconnect_timer_expired,
                                         client);
    }
}
예제 #12
0
static void
add_maybe_redirect_timer (void)
{
  if (dsk_daemon_log_template == NULL)
    return;

  maybe_redirect_stdouterr ();

  unsigned time = dsk_dispatch_default ()->last_dispatch_secs;
  time -= time % dsk_daemon_log_interval;
  time += dsk_daemon_log_interval;

  dsk_main_add_timer (time, 0, (DskTimerFunc) add_maybe_redirect_timer, NULL);
}
예제 #13
0
static void
stream_do_watch_fd (DskClientStream *stream)
{
  if (stream->is_connected)
    {
      int events = 0;
      if (stream->base_instance.source != NULL
       && dsk_hook_is_trapped (&stream->base_instance.source->readable_hook))
        events |= DSK_EVENT_READABLE;
      if (stream->base_instance.sink != NULL
       && dsk_hook_is_trapped (&stream->base_instance.sink->writable_hook))
        events |= DSK_EVENT_WRITABLE;
      dsk_dispatch_watch_fd (dsk_dispatch_default (), stream->fd, events,
                             handle_fd_events, stream);
    }
}
예제 #14
0
void
dsk_client_stream_set_max_idle_time  (DskClientStream *client,
                                      int              millis)
{
  if (millis < 0)
    millis = -1;
  if (millis == client->idle_disconnect_time_ms)
    return;
  if (client->idle_disconnect_timer != NULL)
    {
      dsk_dispatch_remove_timer (client->idle_disconnect_timer);
      client->idle_disconnect_timer = NULL;
    }
  if (millis >= 0
   && client->is_connected)
    client->idle_disconnect_timer = dsk_dispatch_add_timer_millis (dsk_dispatch_default (),
                                                                   millis,
                                                                   handle_idle_too_long,
                                                                   client);
  client->idle_disconnect_time_ms = millis;
}
예제 #15
0
파일: dsk-main.c 프로젝트: davebenson/dsk
void              dsk_main_fd_closed       (DskFileDescriptor   fd)
{
  dsk_dispatch_fd_closed (dsk_dispatch_default (), fd);
}
예제 #16
0
static void
begin_connecting_sockaddr (DskClientStream *stream,
                           unsigned          addr_len,
                           struct sockaddr   *addr)
{
  int fd;
  dsk_assert (stream->fd == -1);
  dsk_assert (!stream->is_connecting);
  dsk_assert (!stream->is_connected);
retry_sys_socket:
  fd = socket (addr->sa_family, SOCK_STREAM, 0);
  if (fd < 0)
    {
      int e = errno;
      if (e == EINTR)
        goto retry_sys_socket;
      if (dsk_fd_creation_failed (e))
        goto retry_sys_socket;

      /* set error */
      dsk_octet_stream_set_last_error (&stream->base_instance,
                                       "error invoking socket(2) system-call: %s",
                                       strerror (e));

      goto handle_error;
    }

  /* set non-blocking */
  dsk_fd_set_nonblocking (fd);
  dsk_fd_set_close_on_exec (fd);

  /* call connect() */
retry_sys_connect:
  if (connect (fd, addr, addr_len) < 0)
    {
      int e = errno;
      if (e == EINTR)
        goto retry_sys_connect;
      
      if (e == EAGAIN || e == EINPROGRESS)
        {
          stream->is_connecting = DSK_TRUE;
          stream->fd = fd;
          dsk_dispatch_watch_fd (dsk_dispatch_default (), fd,
                                 DSK_EVENT_WRITABLE|DSK_EVENT_READABLE,
                                 handle_fd_connecting, stream);
          return;
        }

      /* set error */
      close (fd);
      dsk_octet_stream_set_last_error (&stream->base_instance,
                                       "error connecting to %s: %s",
                                       stream->name, strerror (e));
      goto handle_error;
    }

  stream->is_connected = DSK_TRUE;
  stream->fd = fd;
  handle_fd_connected (stream);
  return;

handle_error:
  maybe_set_autoreconnect_timer (stream);
  return;
}
예제 #17
0
파일: dsk-main.c 프로젝트: davebenson/dsk
DskDispatchIdle  *dsk_main_add_idle        (DskIdleFunc         func,
                                            void               *func_data)
{
  return dsk_dispatch_add_idle (dsk_dispatch_default (), func, func_data);
}