From 00607b678dedef3396c9d9ec48797ec50e4724a5 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Wed, 14 Mar 2007 15:31:18 +0000 Subject: [PATCH] Added silc_thread_yield. Stream destroy fixes if stream isn't scheduled. --- lib/silcutil/DIRECTORY | 4 +-- lib/silcutil/silcfdstream.c | 33 +++++++++++++++------- lib/silcutil/silcfdstream.h | 11 +++++--- lib/silcutil/silcsocketstream.h | 11 ++++---- lib/silcutil/silcthread.h | 14 +++++++++ lib/silcutil/symbian/silcsymbianthread.cpp | 9 ++++++ lib/silcutil/unix/silcunixschedule.c | 8 +++--- lib/silcutil/unix/silcunixthread.c | 8 ++++++ lib/silcutil/win32/silcwin32thread.c | 7 +++++ 9 files changed, 80 insertions(+), 25 deletions(-) diff --git a/lib/silcutil/DIRECTORY b/lib/silcutil/DIRECTORY index 00394a1e..7782933d 100644 --- a/lib/silcutil/DIRECTORY +++ b/lib/silcutil/DIRECTORY @@ -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 diff --git a/lib/silcutil/silcfdstream.c b/lib/silcutil/silcfdstream.c index 67ad3269..5a552847 100644 --- a/lib/silcutil/silcfdstream.c +++ b/lib/silcutil/silcfdstream.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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; diff --git a/lib/silcutil/silcfdstream.h b/lib/silcutil/silcfdstream.h index 0b09fd3a..f5a95e3a 100644 --- a/lib/silcutil/silcfdstream.h +++ b/lib/silcutil/silcfdstream.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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, diff --git a/lib/silcutil/silcsocketstream.h b/lib/silcutil/silcsocketstream.h index 4d4acec7..6bbde63a 100644 --- a/lib/silcutil/silcsocketstream.h +++ b/lib/silcutil/silcsocketstream.h @@ -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); diff --git a/lib/silcutil/silcthread.h b/lib/silcutil/silcthread.h index b13e31ba..c6429a9b 100644 --- a/lib/silcutil/silcthread.h +++ b/lib/silcutil/silcthread.h @@ -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 diff --git a/lib/silcutil/symbian/silcsymbianthread.cpp b/lib/silcutil/symbian/silcsymbianthread.cpp index d4d788dc..c53e4443 100644 --- a/lib/silcutil/symbian/silcsymbianthread.cpp +++ b/lib/silcutil/symbian/silcsymbianthread.cpp @@ -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 */ diff --git a/lib/silcutil/unix/silcunixschedule.c b/lib/silcutil/unix/silcunixschedule.c index 9a4ae9a4..15840ee3 100644 --- a/lib/silcutil/unix/silcunixschedule.c +++ b/lib/silcutil/unix/silcunixschedule.c @@ -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; diff --git a/lib/silcutil/unix/silcunixthread.c b/lib/silcutil/unix/silcunixthread.c index 6e85dd74..fbfb0da2 100644 --- a/lib/silcutil/unix/silcunixthread.c +++ b/lib/silcutil/unix/silcunixthread.c @@ -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 *******************************/ diff --git a/lib/silcutil/win32/silcwin32thread.c b/lib/silcutil/win32/silcwin32thread.c index d54a13e6..f8121fcb 100644 --- a/lib/silcutil/win32/silcwin32thread.c +++ b/lib/silcutil/win32/silcwin32thread.c @@ -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 *******************************/ -- 2.24.0