[go: up one dir, main page]

File: eventqueue.c

package info (click to toggle)
uhub 0.4.1-3.3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,508 kB
  • sloc: ansic: 18,133; xml: 575; perl: 568; sh: 368; makefile: 24
file content (144 lines) | stat: -rw-r--r-- 3,304 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * uhub - A tiny ADC p2p connection hub
 * Copyright (C) 2007-2009, Jan Vidar Krey
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "uhub.h"

#ifdef EQ_DEBUG
static void eq_debug(const char* prefix, struct event_data* data)
{
	LOG_DUMP(">>> %s: %p, id: %x, flags=%d\n", prefix, data, data->id, data->flags);
}
#endif


int event_queue_initialize(struct event_queue** queue, event_queue_callback callback, void* ptr)
{
	*queue = (struct event_queue*) hub_malloc_zero(sizeof(struct event_queue));
	if (!(*queue))
		return -1;
	
	(*queue)->q1 = list_create();
	(*queue)->q2 = list_create();
	
	if (!(*queue)->q1 || !(*queue)->q2)
	{
		list_destroy((*queue)->q1);
		list_destroy((*queue)->q2);
		return -1;
	}
	
	(*queue)->callback = callback;
	(*queue)->callback_data = ptr;
	
	return 0;
}


void event_queue_shutdown(struct event_queue* queue)
{
	/* Should be empty at this point! */
	list_destroy(queue->q1);
	list_destroy(queue->q2);
	hub_free(queue);
}

static void event_queue_cleanup_callback(void* ptr)
{
#ifdef EQ_DEBUG
	struct event_data* data = (struct event_data*) ptr;
	eq_debug("NUKE", data);
#endif

	hub_free((struct event_data*) ptr);
}

int event_queue_process(struct event_queue* queue)
{
	struct event_data* data;
	if (queue->locked)
		return 0;
	
	/* lock primary queue, and handle the primary queue messages. */
	queue->locked = 1;
	
	data = (struct event_data*) list_get_first(queue->q1);
	while (data)
	{
#ifdef EQ_DEBUG
		eq_debug("EXEC", data);
#endif
		queue->callback(queue->callback_data, data);
		data = (struct event_data*) list_get_next(queue->q1);
	}
	
	list_clear(queue->q1, event_queue_cleanup_callback);
	uhub_assert(list_size(queue->q1) == 0);
		
	/* unlock queue */
	queue->locked = 0;
	
	/* transfer from secondary queue to the primary queue. */
	data = (struct event_data*) list_get_first(queue->q2);
	while (data)
	{
		list_remove(queue->q2, data);
		list_append(queue->q1, data);
		data = (struct event_data*) list_get_first(queue->q2);
	}
	
	/* if more events exist, schedule it */
	if (list_size(queue->q1))
	{
		return 1;
	}
	return 0;
}

void event_queue_post(struct event_queue* queue, struct event_data* message)
{
	struct linked_list* q = (!queue->locked) ? queue->q1 : queue->q2;
	struct event_data* data;
	
	data = (struct event_data*) hub_malloc(sizeof(struct event_data));
	if (data)
	{
		data->id    = message->id;
		data->ptr   = message->ptr;
		data->flags = message->flags;
		
#ifdef EQ_DEBUG
		eq_debug("POST", data);
#endif
		
		list_append(q, data);
	}
	else
	{
		LOG_ERROR("event_queue_post: OUT OF MEMORY");
	}
}


size_t event_queue_size(struct event_queue* queue)
{
	return list_size(queue->q1) + list_size(queue->q2);
}