Rewrote SILC Scheduler handling. Use the notify callback instead
authorPekka Riikonen <priikone@silcnet.org>
Wed, 6 Jun 2007 14:33:09 +0000 (14:33 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 6 Jun 2007 14:33:09 +0000 (14:33 +0000)
of polling every few msecs.
Fixed file transfer crash in /QUIT.  CLose FTP sessions in QUIT.

apps/irssi/src/silc/core/silc-core.c
apps/irssi/src/silc/core/silc-servers.c

index abc44b0bc21e11854e9e1f0a5e94d6c200297f2b..e2c189bb15a9844dbce97c8dac34e1afb71a248e 100644 (file)
@@ -50,7 +50,6 @@ static int opt_bits = 0;
 static int init_failed = 0;
 #endif
 
-static int idletag = -1;
 static int running = 0;
 
 /* SILC Client */
@@ -77,10 +76,66 @@ void silc_lag_deinit(void);
 void silc_core_deinit(void);
 #endif
 
-static int my_silc_scheduler(void)
+static gboolean my_silc_scheduler(gpointer data)
 {
+  SILC_LOG_DEBUG(("Timeout"));
   silc_client_run_one(silc_client);
-  return 1;
+  return FALSE;
+}
+
+static gboolean my_silc_scheduler_fd(GIOChannel *source,
+                                     GIOCondition condition,
+                                     gpointer data)
+{
+  SILC_LOG_DEBUG(("I/O event, %d", SILC_PTR_TO_32(data)));
+  silc_client_run_one(silc_client);
+  return TRUE;
+}
+
+static void scheduler_notify_cb(SilcSchedule schedule,
+                               SilcBool added, SilcTask task,
+                               SilcBool fd_task, SilcUInt32 fd,
+                               SilcTaskEvent event,
+                               long seconds, long useconds,
+                               void *context)
+{
+  if (added) {
+    if (fd_task) {
+      /* Add fd */
+      GIOChannel *ch;
+      guint e = 0;
+
+      SILC_LOG_DEBUG(("Add fd %d, events %d", fd, event));
+      g_source_remove_by_user_data(SILC_32_TO_PTR(fd));
+
+      if (event & SILC_TASK_READ)
+       e |= G_IO_IN;
+      if (event & SILC_TASK_WRITE)
+       e |= G_IO_OUT;
+
+      if (e) {
+       ch = g_io_channel_unix_new(fd);
+       g_io_add_watch(ch, e, my_silc_scheduler_fd, SILC_32_TO_PTR(fd));
+      }
+    } else {
+      /* Add timeout */
+      guint t;
+
+      /* Zero timeouts are delievered always immediately, as per
+        SilcSchedule API documentation, no need to add them to glib. */
+      if (!seconds && !useconds)
+       return;
+
+      t = (seconds * 1000) + (useconds / 1000),
+      SILC_LOG_DEBUG(("interval %d msec", t));
+      g_timeout_add(t, my_silc_scheduler, NULL);
+    }
+  } else {
+    if (fd_task) {
+      /* Remove fd */
+      g_source_remove_by_user_data(SILC_32_TO_PTR(fd));
+    }
+  }
 }
 
 static CHATNET_REC *create_chatnet(void)
@@ -604,6 +659,8 @@ static void sig_init_finished(void)
     return;
   }
 
+  silc_schedule_set_notify(silc_client->schedule, scheduler_notify_cb, NULL);
+
   silc_log_set_callback(SILC_LOG_INFO, silc_log_misc, NULL);
   silc_log_set_callback(SILC_LOG_WARNING, silc_log_misc, NULL);
   silc_log_set_callback(SILC_LOG_ERROR, silc_log_misc, NULL);
@@ -611,8 +668,8 @@ static void sig_init_finished(void)
 
   silc_hash_alloc("sha1", &sha1hash);
 
-  /* register SILC scheduler */
-  idletag = g_timeout_add(5, (GSourceFunc) my_silc_scheduler, NULL);
+  /* Run SILC scheduler */
+  my_silc_scheduler(NULL);
 }
 
 /* Init SILC. Called from src/fe-text/silc.c */
@@ -790,12 +847,9 @@ void silc_core_init(void)
 
 void silc_core_deinit(void)
 {
-  if (idletag != -1)
-    g_source_remove(idletag);
-
   if (running) {
     volatile int stopped = 0;
-    silc_client_stop(silc_client, silc_stopped, &stopped);
+    silc_client_stop(silc_client, silc_stopped, (void *)&stopped);
     while (!stopped)
       silc_client_run_one(silc_client);
   }
index 1c121385f7ca8d816450b04ffc087f43c0a539c0..ba0dc80ae19d214a45c2978649ea2d83d62e5975 100644 (file)
@@ -275,6 +275,7 @@ static void silc_connect_cb(SilcClient client,
                            void *context)
 {
   SILC_SERVER_REC *server = context;
+  FtpSession ftp;
   char *file;
 
   SILC_LOG_DEBUG(("Connection callback %p, status %d, error %d, message %s",
@@ -348,6 +349,12 @@ static void silc_connect_cb(SilcClient client,
               silc_get_status_message(error), error,
               message ? message : "");
 
+    /* Close FTP sessions */
+    silc_dlist_start(server->ftp_sessions);
+    while ((ftp = silc_dlist_get(server->ftp_sessions)))
+      silc_client_file_close(client, conn, ftp->session_id);
+    silc_dlist_uninit(server->ftp_sessions);
+
     if (server->conn)
       server->conn->context = NULL;
     server->conn = NULL;
@@ -454,8 +461,6 @@ static void sig_disconnected(SILC_SERVER_REC *server)
   if (!IS_SILC_SERVER(server))
     return;
 
-  silc_dlist_uninit(server->ftp_sessions);
-
   if (server->conn) {
     /* Close connection */
     silc_client_close_connection(silc_client, server->conn);