2 event-queue.h -- New Generation Event Queue
3 Copyright (C) 2006, 2007, 2008 Sebastian Freundt
5 Author: Sebastian Freundt <hroptatyr@sxemacs.org>
7 * This file is part of SXEmacs.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the author nor the names of any contributors
21 * may be used to endorse or promote products derived from this
22 * software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 /* Inspired by XEmacs' events.c written by Jamie Zawinski */
39 /* Synched up with: Not in FSF. */
41 #ifndef INCLUDED_event_queue_h_
42 #define INCLUDED_event_queue_h_
44 #include "semaphore.h"
46 #ifdef ALL_DEBUG_FLAGS
47 #undef EQUEUE_DEBUG_FLAG
48 #define EQUEUE_DEBUG_FLAG
51 #define __EQUEUE_DEBUG__(args...) fprintf(stderr, "event-queue " args)
52 #ifndef EQUEUE_DEBUG_FLAG
53 #define EQUEUE_DEBUG(args...)
55 #define EQUEUE_DEBUG(args...) __EQUEUE_DEBUG__(args)
57 #define EQUEUE_CRITICAL(args...) __EQUEUE_DEBUG__("CRITICAL: " args)
58 #define EQUEUE_DEBUG_WORKER(args...) EQUEUE_DEBUG("[worker] " args)
59 #define EQUEUE_DEBUG_SCRATCH(args...) EQUEUE_DEBUG("[scratch] " args)
61 typedef struct event_queue_s *event_queue_t;
62 typedef struct event_prique_s *event_prique_t;
64 /* a prominent instance */
65 extern event_queue_t asyneq;
68 /* ordinary FIFO-queue */
69 struct event_queue_s {
70 struct lcrecord_header lheader;
71 struct sxe_semaphore_s queue_sem;
75 /* priority queue, pronounced: prick :) */
76 struct event_prique_s {
77 struct lcrecord_header lheader;
78 struct sxe_semaphore_s prique_sem;
79 /* since ase's heap implementation is not global we use a void* here */
83 DECLARE_LRECORD(event_queue, struct event_queue_s);
84 #define eq_queue_sem(_x) ((_x)->queue_sem)
85 #define eq_queue(_x) ((_x)->queue)
86 #define XEVENT_QUEUE(x) XRECORD(x, event_queue, struct event_queue_s)
87 #define XSETEVENT_QUEUE(x, p) XSETRECORD(x, p, event_queue)
88 #define EVENT_QUEUE_P(x) RECORDP(x, event_queue)
90 DECLARE_LRECORD(event_prique, struct event_prique_s);
91 #define eq_prique_sem(_x) ((_x)->prique_sem)
92 #define eq_prique(_x) ((_x)->prique)
93 #define XEVENT_PRIQUE(x) XRECORD(x, event_prique, struct event_prique_s)
94 #define XSETEVENT_PRIQUE(x, p) XSETRECORD(x, p, event_prique)
95 #define EVENT_PRIQUE_P(x) RECORDP(x, event_prique)
98 extern event_queue_t make_noseeum_event_queue(void);
99 extern event_queue_t make_event_queue(void);
100 extern void free_event_queue(event_queue_t);
101 extern event_prique_t make_event_prique(void);
102 extern void free_event_prique(event_prique_t);
104 extern_inline void eq_enqueue(event_queue_t, Lisp_Object);
105 extern_inline Lisp_Object eq_dequeue(event_queue_t);
106 extern_inline void eq_noseeum_enqueue(event_queue_t, void*);
107 extern_inline void *eq_noseeum_dequeue(event_queue_t);
108 extern void eq_enqueue_event_chain(event_queue_t, Lisp_Object);
109 extern_inline size_t eq_queue_size(event_queue_t);
110 extern_inline int eq_queue_empty_p(event_queue_t);
111 extern_inline void eq_queue_synch(event_queue_t);
112 extern_inline void eq_queue_trigger(event_queue_t);
113 extern_inline void eq_queue_trigger_all(event_queue_t);
115 /* special purpose */
116 extern_inline void eq_dequeue_pro(Lisp_Object*, event_queue_t);
120 eq_enqueue(event_queue_t eq, Lisp_Object ev)
122 dllist_append(eq_queue(eq), (void*)ev);
126 extern_inline Lisp_Object
127 eq_dequeue(event_queue_t eq)
129 return (Lisp_Object)(Lisp_Object*)dllist_pop_car(eq_queue(eq));
133 eq_dequeue_pro(Lisp_Object *result, event_queue_t eq)
135 dllist_pop_and_pro_car(result, eq_queue(eq));
140 eq_noseeum_enqueue(event_queue_t eq, void *ev)
142 dllist_append(eq_queue(eq), ev);
147 eq_noseeum_dequeue(event_queue_t eq)
149 return (void*)dllist_pop_car(eq_queue(eq));
153 eq_queue_size(event_queue_t eq)
155 return dllist_get_size(eq_queue(eq));
159 eq_queue_empty_p(event_queue_t eq)
161 return eq_queue_size(eq) == 0;
164 #define RETURN_FROM_EQ_TRAVERSE(_eq, _retval) \
165 RETURN_FROM_DLLIST_TRAVERSE(eq_queue(_eq), _retval)
166 #define EQ_TRAVERSE(_eq, _var, args...) \
167 WITH_DLLIST_TRAVERSE( \
169 _var = (Lisp_Object)dllist_item; \
174 eq_queue_synch(event_queue_t eq)
176 SXE_SEMAPH_SYNCH(&eq_queue_sem(eq));
180 eq_queue_trigger(event_queue_t eq)
182 SXE_SEMAPH_TRIGGER(&eq_queue_sem(eq));
186 eq_queue_trigger_all(event_queue_t eq)
188 SXE_SEMAPH_TRIGGER_ALL(&eq_queue_sem(eq));
191 #endif /* INCLUDED_event_queue_h_ */