]> mj.ucw.cz Git - libucw.git/commitdiff
Main: Removing an already removed event is always safe.
authorMartin Mares <mj@ucw.cz>
Thu, 9 Feb 2012 19:20:34 +0000 (20:20 +0100)
committerMartin Mares <mj@ucw.cz>
Thu, 9 Feb 2012 19:20:34 +0000 (20:20 +0100)
Also adding an already added hook is always safe. For other event
types, we still refuse repeated adds.

ucw/doc/relnotes.txt
ucw/main-rec.c
ucw/mainloop.c
ucw/mainloop.h

index add13974be5e8166b1b32245222cfd46999455b7..11b1661744bec52c75cd4e89374a225cf60437ea 100644 (file)
@@ -23,7 +23,8 @@ Release notes
    or <<mainloop:fun_main_destroy,`main_destroy()`>> to clean up properly after fork().
 ** Added support for <<mainloop:signal,synchronous delivery of signals>>.
 ** Added relative timers: <<mainloop:fun_timer_add_rel,`timer_add_rel()`>>.
-** Modification of events from a running event handler should be always safe.
+** Modification of events from a running event handler is always safe.
+** Deleting an already deleted event is always safe.
 ** For any event type, it is possible to ask whether it is active (added to the mainloop) or not: <<mainloop:fun_hook_is_active,`hook_is_active()`>> and friends.
 ** A new mainloop front-end for asynchronous <<mainloop:recordio,record-based I/O>> has been added.
 
index df23427ddaf8390779f589cb9eec6ef0a522afee..1db9942b78f81ca0278c6430e35eb37ac3a9003a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     UCW Library -- Main Loop: Record I/O
  *
- *     (c) 2011 Martin Mares <mj@ucw.cz>
+ *     (c) 2011--2012 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
@@ -51,9 +51,11 @@ rec_io_add(struct main_rec_io *rio, int fd)
 void
 rec_io_del(struct main_rec_io *rio)
 {
+  if (!rec_io_is_active(rio))
+    return;
+
   timer_del(&rio->timer);
-  if (hook_is_active(&rio->start_read_hook))
-    hook_del(&rio->start_read_hook);
+  hook_del(&rio->start_read_hook);
   file_del(&rio->file);
 
   if (rio->read_buf)
index 454ea81c2776c7316d4a651889e3fcddd54444af..52a634898d73327b9a86cee232678795caa25e33 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     UCW Library -- Main Loop
  *
- *     (c) 2004--2011 Martin Mares <mj@ucw.cz>
+ *     (c) 2004--2012 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
@@ -355,7 +355,8 @@ file_del_ctx(struct main_context *m, struct main_file *fi)
   // XXX: Can be called on a non-current context
   DBG("MAIN: Deleting file %p (fd=%d)", fi, fi->fd);
 
-  ASSERT(file_is_active(fi));
+  if (!file_is_active(fi))
+    return;
   clist_unlink(&fi->n);
   m->file_cnt--;
 #ifdef CONFIG_UCW_EPOLL
@@ -378,16 +379,16 @@ hook_add(struct main_hook *ho)
   struct main_context *m = main_current();
 
   DBG("MAIN: Adding hook %p", ho);
-  ASSERT(!hook_is_active(ho));
-  clist_add_tail(&m->hook_list, &ho->n);
+  if (!hook_is_active(ho))
+    clist_add_tail(&m->hook_list, &ho->n);
 }
 
 void
 hook_del(struct main_hook *ho)
 {
   DBG("MAIN: Deleting hook %p", ho);
-  ASSERT(hook_is_active(ho));
-  clist_unlink(&ho->n);
+  if (hook_is_active(ho))
+    clist_unlink(&ho->n);
 }
 
 static void
@@ -436,8 +437,8 @@ void
 process_del(struct main_process *mp)
 {
   DBG("MAIN: Deleting process %p (pid=%d)", mp, mp->pid);
-  ASSERT(process_is_active(mp));
-  clist_unlink(&mp->n);
+  if (process_is_active(mp))
+    clist_unlink(&mp->n);
 }
 
 int
@@ -568,7 +569,8 @@ signal_del_ctx(struct main_context *m, struct main_signal *ms)
   // XXX: Can be called on a non-current context
   DBG("MAIN: Deleting signal %p (sig=%d)", ms, ms->signum);
 
-  ASSERT(signal_is_active(ms));
+  if (!signal_is_active(ms))
+    return;
   clist_unlink(&ms->n);
 
   int another = 0;
index 6de703d862f747687229d4cac5df5f03629083c2..9cd97453a96b54e2466a85736e58c3d4b1760df4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     UCW Library -- Main Loop
  *
- *     (c) 2004--2011 Martin Mares <mj@ucw.cz>
+ *     (c) 2004--2012 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
@@ -178,7 +178,7 @@ void timer_add_rel(struct main_timer *tm, timestamp_t expires_delta);
 /**
  * Removes a timer from the active ones. It is permitted (and common) to call
  * this function from the timer's handler itself if you want to deactivate
- * the timer.
+ * the timer. Removing an already removed timer does nothing.
  **/
 void timer_del(struct main_timer *tm);
 
@@ -247,12 +247,14 @@ enum main_hook_return {
  * Inserts a new hook into the loop.
  * The hook will be scheduled at least once before next sleep.
  * May be called from inside a hook handler too.
+ * Adding an already added hook does nothing.
  **/
 void hook_add(struct main_hook *ho);
 
 /**
  * Removes an existing hook from the loop.
  * May be called from inside a hook handler (to delete itself or another hook).
+ * Removing an already removed hook does nothing.
  **/
 void hook_del(struct main_hook *ho);
 
@@ -339,6 +341,7 @@ void file_chg(struct main_file *fi);
  * please use this function first.
  *
  * Can be called from a handler.
+ * Removing an already removed file does nothing.
  **/
 void file_del(struct main_file *fi);
 
@@ -391,7 +394,7 @@ struct main_block_io {
 /** Activate a block I/O structure. **/
 void block_io_add(struct main_block_io *bio, int fd);
 
-/** Deactivate a block I/O structure. **/
+/** Deactivate a block I/O structure. Calling twice is safe. **/
 void block_io_del(struct main_block_io *bio);
 
 /**
@@ -518,7 +521,7 @@ struct main_rec_io {
 /** Activate a record I/O structure. **/
 void rec_io_add(struct main_rec_io *rio, int fd);
 
-/** Deactivate a record I/O structure. **/
+/** Deactivate a record I/O structure. Calling twice is safe. **/
 void rec_io_del(struct main_rec_io *rio);
 
 /**
@@ -607,6 +610,7 @@ void process_add(struct main_process *mp);
  * Removes the process from the watched set. This is done
  * automatically, when the process terminates, so you need it only
  * when you do not want to watch a running process any more.
+ * Removing an already removed process does nothing.
  */
 void process_del(struct main_process *mp);
 
@@ -672,7 +676,7 @@ struct main_signal {
 /** Request a signal to be caught and delivered synchronously. **/
 void signal_add(struct main_signal *ms);
 
-/** Cancel a request for signal catching. **/
+/** Cancel a request for signal catching. Calling twice is safe. **/
 void signal_del(struct main_signal *ms);
 
 /** Tells if a signal catcher is active (i.e., added). **/