Added silc_thread_yield.
authorPekka Riikonen <priikone@silcnet.org>
Wed, 14 Mar 2007 15:31:18 +0000 (15:31 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 14 Mar 2007 15:31:18 +0000 (15:31 +0000)
Stream destroy fixes if stream isn't scheduled.

lib/silcutil/DIRECTORY
lib/silcutil/silcfdstream.c
lib/silcutil/silcfdstream.h
lib/silcutil/silcsocketstream.h
lib/silcutil/silcthread.h
lib/silcutil/symbian/silcsymbianthread.cpp
lib/silcutil/unix/silcunixschedule.c
lib/silcutil/unix/silcunixthread.c
lib/silcutil/win32/silcwin32thread.c

index 00394a1e14c075fabc74d6d3c03c75c30d00a417..7782933dec7b49cbf9322a8a85f5bb0279bcdb69 100644 (file)
@@ -7,9 +7,10 @@
 @LINK=silchashtable.html:Hash Table Interface
 @LINK=silcmemory.html:Memory Allocation Interface
 @LINK=silcstack.html:Data Stack (memory pool) Interface
+@LINK=silcfsm.html:Finite State Machine Interface
 @LINK=silcthread.html:Thread Interface
 @LINK=silcmutex.html:Mutual Exclusion Lock Interface
-@LINK=silccond.html:Conditional Variable Interface
+@LINK=silccond.html:Condition Variable Interface
 @LINK=silcatomic.html:Atomic Operations Interface
 @LINK=silcnet.html:Network (TCP and UDP) Interface
 @LINK=silcschedule.html:Scheduler Interface
@@ -17,7 +18,6 @@
 @LINK=silcstream.html:Abstract Stream Interface
 @LINK=silcsocketstream.html:Socket Stream Interface
 @LINK=silcfdstream.html:File Descriptor Stream Interface
-@LINK=silcfsm.html:Finite State Machine Interface
 @LINK=silcfileutil.html:File Utility Functions
 @LINK=silcstrutil.html:String Utility Interface
 @LINK=silcsnprintf.html:Snprintf Interface
index 67ad3269c7f514d2e1ee1f5ccbc59b81877ee92c..5a552847e0702a7c68b77906ffa2a1bdceea05ab 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2005 - 2006 Pekka Riikonen
+  Copyright (C) 2005 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -102,10 +102,13 @@ SilcStream silc_fd_stream_file(const char *filename,
                               SilcBool reading, SilcBool writing)
 {
   int fd, flags = 0;
+  SilcStream stream;
 
   if (!filename)
     return NULL;
 
+  SILC_LOG_DEBUG(("Creating new fd stream for file `%s'", filename));
+
   if (reading)
     flags |= O_RDONLY;
   if (writing)
@@ -117,7 +120,11 @@ SilcStream silc_fd_stream_file(const char *filename,
   if (fd < 0)
     return NULL;
 
-  return silc_fd_stream_create(fd);
+  stream = silc_fd_stream_create(fd);
+  if (!stream)
+    silc_file_close(fd);
+
+  return stream;
 }
 
 /* Return fds */
@@ -232,13 +239,17 @@ SilcBool silc_fd_stream_close(SilcStream stream)
 
   if (fd_stream->fd1 > 0) {
     silc_file_close(fd_stream->fd1);
-    silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1);
-    silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd1);
+    if (fd_stream->schedule) {
+      silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1);
+      silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd1);
+    }
   }
   if (fd_stream->fd2 > 0 && fd_stream->fd2 != fd_stream->fd1) {
     silc_file_close(fd_stream->fd2);
-    silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2);
-    silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd2);
+    if (fd_stream->schedule) {
+      silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2);
+      silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd2);
+    }
   }
 
   return TRUE;
@@ -284,10 +295,12 @@ SilcBool silc_fd_stream_notifier(SilcStream stream,
        fd_stream->fd2 = fd_stream->fd1;
     }
   } else {
-    silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1);
-    silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2);
-    silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd1);
-    silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd2);
+    if (fd_stream->schedule) {
+      silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1);
+      silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2);
+      silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd1);
+      silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd2);
+    }
   }
 
   return TRUE;
index 0b09fd3a520ed8f148d6cf56b7d09dcdca91057e..f5a95e3a6f50b6a7b60b7e2ef2f46c162b51fb76 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2005 Pekka Riikonen
+  Copyright (C) 2005 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -47,7 +47,8 @@
  *    with the silc_stream_destroy.
  *
  *    The silc_stream_set_notifier must be called in order to be able to read
- *    from and write to this file descriptor stream.
+ *    from and write to this file descriptor stream if the `fd' is in
+ *    non-blocking mode.
  *
  ***/
 SilcStream silc_fd_stream_create(int fd);
@@ -66,7 +67,8 @@ SilcStream silc_fd_stream_create(int fd);
  *    silc_stream_close and destroyed with the silc_stream_destroy.
  *
  *    The silc_stream_set_notifier must be called in order to be able to read
- *    from and write to this file descriptor stream.
+ *    from and write to this file descriptor stream if the `fd' is in
+ *    non-blocking mode.
  *
  ***/
 SilcStream silc_fd_stream_create2(int read_fd, int write_fd);
@@ -86,7 +88,8 @@ SilcStream silc_fd_stream_create2(int read_fd, int write_fd);
  *    for writing.
  *
  *    The silc_stream_set_notifier must be called in order to be able to read
- *    from and write to this file descriptor stream.
+ *    from and write to this file descriptor stream if the `fd' is in
+ *    non-blocking mode.
  *
  ***/
 SilcStream silc_fd_stream_file(const char *filename, SilcBool reading,
index 4d4acec73878d6351a836d062e93483586d09076..6bbde63aa5a982c51be76d5f9b5aba8e314527c7 100644 (file)
@@ -102,7 +102,7 @@ typedef void (*SilcSocketStreamCallback)(SilcSocketStreamStatus status,
  *    socket connection information, such as hostname and IP address are
  *    resolved, so SilcAsyncOperation is returned which can be used to cancel
  *    the creation process.  The `callback' will be called to return the
- *    created socket stream.  To destroy the stream call silc_stream_destroy.
+ *    created socket stream.
  *
  *    If the `lookup' is TRUE then this will perform IP and hostname lookup
  *    for the socket.  If the `require_fqdn' is TRUE then the socket must
@@ -168,10 +168,11 @@ SilcStream silc_socket_udp_stream_create(SilcSocket sock,
  * DESCRIPTION
  *
  *    Returns TRUE if the `stream' is UDP stream.  If the `connected' pointer
- *    is non-NULL indication whether the UDP stream is in connected state.
- *    If it is then packets can be read and written using silc_stream_read
- *    and silc_stream_write.  If it is not then packets need to read and
- *    written by using silc_net_udp_receive and silc_net_udp_send.
+ *    is non-NULL it will have indication whether the UDP stream is in
+ *    connected state.  If it is then packets can be read and written using
+ *    silc_stream_read and silc_stream_write.  If it is not then packets
+ *    need to read and written by using silc_net_udp_receive and
+ *    silc_net_udp_send.
  *
  ***/
 SilcBool silc_socket_stream_is_udp(SilcStream stream, SilcBool *connected);
index b13e31ba655a7a67d0a530a22e23a52f8395accf..c6429a9b63740c39791d0b5f29a17c0f41718664 100644 (file)
@@ -144,4 +144,18 @@ SilcThread silc_thread_self(void);
  ***/
 SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
 
+/****f* silcutil/SilcThreadAPI/silc_thread_yield
+ *
+ * SYNOPSIS
+ *
+ *    void silc_thread_yield(void);
+ *
+ * DESCRIPTION
+ *
+ *    Yield the processor.  The calling thread will yield the processor and
+ *    give execution time for other threads, until its turn comes up again.
+ *
+ ***/
+void silc_thread_yield(void);
+
 #endif
index d4d788dc81824f279bd001b94752968c00650561..c53e444385ef83bf4865f2f353feb9e19f4f9752 100644 (file)
@@ -142,6 +142,15 @@ SilcBool silc_thread_wait(SilcThread thread, void **exit_value)
 #endif
 }
 
+/* Yield processor */
+
+void silc_thread_yield(void)
+{
+#ifdef SILC_THREADS
+  User::After(1);
+#endif /* SILC_THREADS */
+}
+
 /***************************** SILC Mutex API *******************************/
 
 /* SILC Mutex structure */
index 9a4ae9a49a192c1f507055bed2d9d443773d7a6c..15840ee3fb67292549d17715c0cce5f0962a912b 100644 (file)
@@ -123,7 +123,7 @@ int silc_poll(SilcSchedule schedule, void *context)
   int fd, ret, i = 0, timeout = -1;
 
   silc_hash_table_list(schedule->fd_queue, &htl);
-  while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task)) {
+  while (silc_hash_table_get(&htl, (void *)&fd, (void *)&task)) {
     if (!task->events)
       continue;
 
@@ -172,7 +172,7 @@ int silc_poll(SilcSchedule schedule, void *context)
     if (!fds[i].revents)
       continue;
     if (!silc_hash_table_find(schedule->fd_queue, SILC_32_TO_PTR(fds[i].fd),
-                             NULL, (void **)&task))
+                             NULL, (void *)&task))
       continue;
     if (!task->header.valid || !task->events)
       continue;
@@ -203,7 +203,7 @@ int silc_select(SilcSchedule schedule, void *context)
   FD_ZERO(&out);
 
   silc_hash_table_list(schedule->fd_queue, &htl);
-  while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task)) {
+  while (silc_hash_table_get(&htl, (void *)&fd, (void *)&task)) {
     if (!task->events)
       continue;
 
@@ -233,7 +233,7 @@ int silc_select(SilcSchedule schedule, void *context)
     return ret;
 
   silc_hash_table_list(schedule->fd_queue, &htl);
-  while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task)) {
+  while (silc_hash_table_get(&htl, (void *)&fd, (void *)&task)) {
     if (!task->header.valid || !task->events)
       continue;
 
index 6e85dd743981702723a8f34e7a006d3eb8ef73d4..fbfb0da254c697596f9f2c4ee75fbbaf52c47bac 100644 (file)
@@ -97,6 +97,14 @@ SilcBool silc_thread_wait(SilcThread thread, void **exit_value)
 #endif
 }
 
+void silc_thread_yield(void)
+{
+#ifdef SILC_THREADS
+#ifdef HAVE_SCHED_YIELD
+  sched_yield();
+#endif /* HAVE_SCHED_YIELD */
+#endif /* SILC_THREADS */
+}
 
 /***************************** SILC Mutex API *******************************/
 
index d54a13e6c83088fd13ca9f8be2c359e5f7fa5d5c..f8121fcbfc4a2d809b9e65e78486b73ef047e7f3 100644 (file)
@@ -146,6 +146,13 @@ SilcBool silc_thread_wait(SilcThread thread, void **exit_value)
 #endif
 }
 
+void silc_thread_yield(void)
+{
+#ifdef SILC_THREADS
+  SleepEx (0,0);
+#endif /* SILC_THREADS */
+}
+
 
 /***************************** SILC Mutex API *******************************/