FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
event.c
Go to the documentation of this file.
1 /* **************************************************************
2 Copyright (C) 2010, 2011, 2012 Hewlett-Packard Development Company, L.P.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 version 2 as published by the Free Software Foundation.
7 
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  ************************************************************** */
22 /* local includes */
23 #include <event.h>
24 #include <logging.h>
25 #include <scheduler.h>
26 
27 /* std libaray includes */
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 
32 /* ************************************************************************** */
33 /* **** Local(private) fields *********************************************** */
34 /* ************************************************************************** */
35 
41 
46 int el_created = 0;
47 
60 {
61 
62  /* if the event loop has already been created, return it */
63  if(el_created)
64  {
65  return &vl_singleton;
66  }
67 
68  vl_singleton.queue = g_async_queue_new_full((GDestroyNotify)event_destroy);
69  vl_singleton.occupied = 0;
70  vl_singleton.terminated = 0;
71  el_created = 1;
72 
73  return &vl_singleton;
74 }
75 
87 {
88  g_async_queue_push(event_loop->queue, e);
89  return 1;
90 }
91 
102 {
103  GTimeVal timeout;
104  event_t* ret;
105 
106  if(event_loop->terminated)
107  {
108  return NULL;
109  }
110 
111  /* wait for 1 second */
112  timeout.tv_sec = 1;
113  timeout.tv_usec = 0;
114 
115 #if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 32
116  if((ret = g_async_queue_timeout_pop(event_loop->queue,
117  timeout.tv_sec * 1000000 + timeout.tv_usec)) == NULL)
118  return ret;
119 #else
120  g_get_current_time(&timeout);
121  g_time_val_add(&timeout, 1000000);
122  if((ret = g_async_queue_timed_pop(event_loop->queue, &timeout)) == NULL)
123  return ret;
124 #endif
125 
126  if(ret->func == NULL)
127  {
128  event_destroy(ret);
129  ret = NULL;
130  }
131 
132  return ret;
133 }
134 
135 /* ************************************************************************** */
136 /* **** Constructor Destructor ********************************************** */
137 /* ************************************************************************** */
138 
153 event_t* event_init(void(*func)(scheduler_t*, void*), void* arg, char* name, char* source_name, uint16_t source_line)
154 {
155  event_t* e = g_new(event_t, 1);
156 
157  e->func = func;
158  e->argument = arg;
159  e->name = name;
160  e->source_name = source_name;
161  e->source_line = source_line;
162 
163  return e;
164 }
165 
172 {
173  e->func = NULL;
174  e->argument = NULL;
175  e->name = NULL;
176 
177  g_free(e);
178 }
179 
186 {
187  g_async_queue_unref(event_loop_get()->queue);
188  el_created = 0;
189 }
190 
191 /* ************************************************************************** */
192 /* **** EventLoop Functions ************************************************* */
193 /* ************************************************************************** */
194 
206 void event_signal_ext(void* func, void* args, char* name, char* s_name, uint16_t s_line)
207 {
208  V_EVENT("EVENT: creating event: [%p, %p, %s, %s, %d]", func, args, name, s_name, s_line);
209  event_loop_put(event_loop_get(), event_init((event_function)func, args, name, s_name, s_line));
210 }
211 
228  void(*update_call)(scheduler_t*),
229  void(*signal_call)(scheduler_t*))
230 {
231  event_t* e;
233 
234  /* start by checking to make sure this is the only thread in this loop */
235  g_async_queue_lock(event_loop->queue);
236  if(event_loop->occupied)
237  {
238  g_async_queue_unlock(event_loop->queue);
239  return 0x1;
240  }
241  event_loop->occupied = 1;
242  event_loop->terminated = 0;
243  g_async_queue_unlock(event_loop->queue);
244 
245  main_thread = g_thread_self();
246 
247  /* from here on out, this is the only thread in this event loop */
248  /* the loop to execute events is very simple, grab event, run event */
249  while(!event_loop->terminated)
250  {
251  e = event_loop_take(event_loop);
252 
253  if(signal_call)
254  signal_call(scheduler);
255  if(e == NULL)
256  continue;
257 
258  if(TVERB_EVENT && strcmp(e->name, "log_event") != 0)
259  log_printf("EVENT: calling %s, source[%s.%d] \n", e->name, e->source_name, e->source_line);
260  e->func(scheduler, e->argument);
261 
262  if(TVERB_EVENT && strcmp(e->name, "log_event") != 0)
263  log_printf("EVENT: finished %s, source[%s.%d] \n", e->name, e->source_name, e->source_line);
264 
265  event_destroy(e);
266 
267  if(update_call)
268  update_call(scheduler);
269  }
270 
271  return 0x0;
272 }
273 
282 {
284 
285  event_loop->terminated = 1;
286  event_loop->occupied = 0;
287  event_signal(NULL, NULL);
288 }
int event_loop_put(event_loop_t *event_loop, event_t *e)
Definition: event.c:86
void event_destroy(event_t *e)
Free any memory associated with an event.
Definition: event.c:171
char * name
Name of the event, used for debugging.
Definition: event.h:38
Log related operations.
int occupied
Does this loop already have a worker thread.
Definition: event.h:47
event_t * event_init(void(*func)(scheduler_t *, void *), void *arg, char *name, char *source_name, uint16_t source_line)
Definition: event.c:153
void event_loop_terminate()
Stops the event loop from executing.
Definition: event.c:281
void event_signal_ext(void *func, void *args, char *name, char *s_name, uint16_t s_line)
Definition: event.c:206
uint16_t s_line
Sample source line number.
Definition: testEvent.c:39
event_t * event_loop_take(event_loop_t *event_loop)
Definition: event.c:101
void * argument
The arguments for the function.
Definition: event.h:37
void(* func)(scheduler_t *, void *)
The function that will be executed for this event.
Definition: event.h:36
uint16_t source_line
Line in the source file creating the event.
Definition: event.h:40
int el_created
Definition: event.c:46
Event handling operations.
event_loop_t vl_singleton
Definition: event.c:40
Definition: event.h:35
GAsyncQueue * queue
The queue that is the core of the event loop.
Definition: event.h:45
GThread * main_thread
Pointer to the main thread.
Definition: scheduler.c:71
void event_loop_destroy()
Frees any memory associated with the event queue.
Definition: event.c:185
Header file for the scheduler.
char * source_name
Name of the source file creating the event.
Definition: event.h:39
char * s_name
Sample source file name.
Definition: testEvent.c:38
event_loop_t * event_loop_get()
Definition: event.c:59
int terminated
Flag that signals the end of the event loop.
Definition: event.h:46
int event_loop_enter(scheduler_t *scheduler, void(*update_call)(scheduler_t *), void(*signal_call)(scheduler_t *))
Enters the event loop.
Definition: event.c:227