1 /* $NetBSD: defer-internal.h,v 1.1.1.1 2013/04/11 16:43:21 christos Exp $ */ 2 /* 3 * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #ifndef _DEFER_INTERNAL_H_ 28 #define _DEFER_INTERNAL_H_ 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include "event2/event-config.h" 35 #include <sys/queue.h> 36 37 struct deferred_cb; 38 39 typedef void (*deferred_cb_fn)(struct deferred_cb *, void *); 40 41 /** A deferred_cb is a callback that can be scheduled to run as part of 42 * an event_base's event_loop, rather than running immediately. */ 43 struct deferred_cb { 44 /** Links to the adjacent active (pending) deferred_cb objects. */ 45 TAILQ_ENTRY (deferred_cb) cb_next; 46 /** True iff this deferred_cb is pending in an event_base. */ 47 unsigned queued : 1; 48 /** The function to execute when the callback runs. */ 49 deferred_cb_fn cb; 50 /** The function's second argument. */ 51 void *arg; 52 }; 53 54 /** A deferred_cb_queue is a list of deferred_cb that we can add to and run. */ 55 struct deferred_cb_queue { 56 /** Lock used to protect the queue. */ 57 void *lock; 58 59 /** How many entries are in the queue? */ 60 int active_count; 61 62 /** Function called when adding to the queue from another thread. */ 63 void (*notify_fn)(struct deferred_cb_queue *, void *); 64 void *notify_arg; 65 66 /** Deferred callback management: a list of deferred callbacks to 67 * run active the active events. */ 68 TAILQ_HEAD (deferred_cb_list, deferred_cb) deferred_cb_list; 69 }; 70 71 /** 72 Initialize an empty, non-pending deferred_cb. 73 74 @param deferred The deferred_cb structure to initialize. 75 @param cb The function to run when the deferred_cb executes. 76 @param arg The function's second argument. 77 */ 78 void event_deferred_cb_init(struct deferred_cb *, deferred_cb_fn, void *); 79 /** 80 Cancel a deferred_cb if it is currently scheduled in an event_base. 81 */ 82 void event_deferred_cb_cancel(struct deferred_cb_queue *, struct deferred_cb *); 83 /** 84 Activate a deferred_cb if it is not currently scheduled in an event_base. 85 */ 86 void event_deferred_cb_schedule(struct deferred_cb_queue *, struct deferred_cb *); 87 88 #define LOCK_DEFERRED_QUEUE(q) \ 89 EVLOCK_LOCK((q)->lock, 0) 90 #define UNLOCK_DEFERRED_QUEUE(q) \ 91 EVLOCK_UNLOCK((q)->lock, 0) 92 93 #ifdef __cplusplus 94 } 95 #endif 96 97 void event_deferred_cb_queue_init(struct deferred_cb_queue *); 98 struct deferred_cb_queue *event_base_get_deferred_cb_queue(struct event_base *); 99 100 #endif /* _EVENT_INTERNAL_H_ */ 101 102