design_pattern_for_c  V 1.00
event_if_libev.c
Go to the documentation of this file.
1 /*
2  * libevent_if_libev plugin for threadpool, used libev (developed Marc Alexander Lehmann)
3  *
4  * Redistribution and use in source and binary forms, with or without modifica-
5  * tion, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
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  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
16  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
18  * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
22  * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23  * OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * the GNU General Public License ("GPL") version 2 or any later version,
27  * in which case the provisions of the GPL are applicable instead of
28  * the above. If you wish to allow the use of your version of this file
29  * only under the terms of the GPL and not to allow others to use your
30  * version of this file under the BSD license, indicate your decision
31  * by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL. If you do not delete the
33  * provisions above, a recipient may use your version of this file under
34  * either the BSD or the GPL.
35  */
36 #include "tpool_event_if.h"
37 #include "dp_util.h"
38 #include <ev.h>
39 #include <unistd.h>
40 #include <sys/eventfd.h>
41 
43  struct ev_loop * loop;
44  int is_stop;
45 };
46 
48 
51  void (*event_callback)(int socketfd, int eventflag, void * event_arg);
52  void *arg;
53  ev_io watch;
54 };
55 
57 
58 static inline int convert_etpoll_eveid2own(int eventflag) {
59  int ret_eveflag=0;
60  if(eventflag&EV_TPOOL_READ) ret_eveflag |= EV_READ;
61  if(eventflag&EV_TPOOL_WRITE) ret_eveflag |= EV_WRITE;
62  if(eventflag&EV_TPOOL_HUNGUP) ret_eveflag |= EV_ERROR;
63  return ret_eveflag;
64 }
65 
66 static inline int convert_etpoll_own2eveid(int eventflag) {
67  int ret_eveflag=0;
68  if(eventflag&EV_READ) ret_eveflag |= EV_TPOOL_READ;
69  if(eventflag&EV_WRITE) ret_eveflag |= EV_TPOOL_WRITE;
70  if(eventflag&EV_ERROR) ret_eveflag |= EV_TPOOL_HUNGUP;
71  return ret_eveflag;
72 }
73 
75  int is_stop;
76  is_stop = this->is_stop;
77  return is_stop;
78 }
79 
80 static void event_if_subscribe_cb(EV_P_ ev_io *w, int revents) {
81  EventLibevHandler handler = (EventLibevHandler)w->data;
82  if(event_if_is_stop(handler->base)) return;
83 
84  int eventflag = convert_etpoll_own2eveid(revents);
85 
86  handler->event_callback(handler->watch.fd, eventflag, handler->arg);
87 }
88 
90  handler->base=base;
91  handler->event_callback = subscriber->event_callback;
92  handler->arg = arg;
93  /*initialize watch*/
94  ev_io_init(&handler->watch, event_if_subscribe_cb, subscriber->fd, convert_etpoll_eveid2own(subscriber->eventflag));
95  /*set user data*/
96  handler->watch.data = handler;
97 
98  /*start watch*/
99  ev_io_start(base->loop, &handler->watch);
100 }
101 
106  EventLibevManager instance = calloc(1, sizeof(*instance));
107  if(!instance) return NULL;
108 
109  instance->loop = ev_loop_new(0);
110  if(!instance->loop) goto err;
111 
112  return instance;
113 err:
114 
115  free(instance);
116  return NULL;
117 }
118 
121 
123 
124  /*add event*/
125  EventLibevHandler handler = calloc(1, sizeof(*handler));
126  if(!handler) {
127  DEBUG_ERRPRINT("Failed to new event!\n" );
128  return NULL;
129  }
130 
131  event_if_libev_handler_init(base, handler, subscriber, arg);
132  return handler;
133 }
134 
136 void * event_if_update(EventInstance this, EventHandler handler, EventSubscriber subscriber, void *arg) {
138  EventLibevHandler libev_handler = (EventLibevHandler)handler;
139  if(event_if_is_stop((EventLibevManager)this)) return NULL;
140 
141  /*stop first*/
142  ev_io_stop(base->loop, &libev_handler->watch);
143 
144  /*re-add*/
145  event_if_libev_handler_init(base, libev_handler, subscriber, arg);
146 
147  return handler;
148 }
149 
153  EventLibevHandler libev_handler = (EventLibevHandler) handler;
154  if(event_if_is_stop((EventLibevManager)this)) return;
155 
156  ev_io_stop(base->loop, &libev_handler->watch);
157  free(libev_handler);
158 }
159 
161  return ((EventLibevHandler)handler)->watch.fd;
162 }
163 
167  ev_loop (base->loop, 0);
168  return 0;
169 }
170 
174  base->is_stop = 1;
175  ev_unloop (base->loop, EVUNLOOP_ONE);
176 }
177 
181  ev_loop_destroy(base->loop);
182 }
183 
187  free(base);
188 }
#define EV_TPOOL_READ
void * event_if_update(EventInstance this, EventHandler handler, EventSubscriber subscriber, void *arg)
update registered event
Utility headers
void(* event_callback)(int socketfd, int eventflag, void *event_arg)
void event_if_free(EventInstance this)
free event if instance
int event_if_getfd(EventHandler handler)
get fd related to handler
void(* free)(EventInstance this)
Definition: event_thread.c:39
int event_if_loop(EventInstance this)
main loop to wait event
#define EV_TPOOL_WRITE
static int event_if_is_stop(EventLibevManager this)
static int convert_etpoll_eveid2own(int eventflag)
void(* event_callback)(int socketfd, int eventflag, void *event_arg)
EventHandler event_if_add(EventInstance this, EventSubscriber subscriber, void *arg)
add new event
struct ev_loop * loop
void * EventHandler
Event handler related to fd.
EventSubscriber class instance definition, this is storaged in any threads.
struct event_libev_handler_t * EventLibevHandler
int eventflag
OR value of EV_TPOOL_XXX definition.
void event_if_del(EventInstance this, EventHandler handler)
delete event
#define EV_TPOOL_HUNGUP
int fd
file descripter of this subscriber
void * EventInstance
Event management instance which get from event_if_new.
struct event_libev_manager_t * EventLibevManager
#define DEBUG_ERRPRINT(...)
Definition: dp_debug.h:69
static void event_if_subscribe_cb(EV_P_ ev_io *w, int revents)
EventInstance event_if_new(void)
event new
static int convert_etpoll_own2eveid(int eventflag)
EventLibevManager base
static void event_if_libev_handler_init(EventLibevManager base, EventLibevHandler handler, EventSubscriber subscriber, void *arg)
void event_if_loopbreak(EventInstance this)
break event
void event_if_exit(EventInstance this)
exit after main loop