Stream destroy fixes if stream isn't scheduled.
@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
@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
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
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)
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 */
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;
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;
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
* 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);
* 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);
* 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,
* 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
* 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);
***/
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
#endif
}
+/* Yield processor */
+
+void silc_thread_yield(void)
+{
+#ifdef SILC_THREADS
+ User::After(1);
+#endif /* SILC_THREADS */
+}
+
/***************************** SILC Mutex API *******************************/
/* SILC Mutex structure */
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;
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;
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;
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;
#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 *******************************/
#endif
}
+void silc_thread_yield(void)
+{
+#ifdef SILC_THREADS
+ SleepEx (0,0);
+#endif /* SILC_THREADS */
+}
+
/***************************** SILC Mutex API *******************************/