1 /* distcache, Distributed Session Caching technology
2  * Copyright (C) 2000-2003  Geoff Thorpe, and Cryptographic Appliances, Inc.
3  * Copyright (C) 2004       The Distcache.org project
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License as published by the Free
7  * Software Foundation; using version 2.1 of the License. The copyright holders
8  * may elect to allow the application of later versions of the License to this
9  * software, please contact the author (geoff@distcache.org) if you wish us to
10  * review any later version released by the Free Software Foundation.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 
22 #define SYS_GENERATING_LIB
23 
24 #include <libsys/pre.h>
25 #include <libnal/nal.h>
26 #include "nal_internal.h"
27 #include <libsys/post.h>
28 
29 struct st_NAL_SELECTOR {
30 	/* Implementation (or NULL if not set) */
31 	const NAL_SELECTOR_vtable *vt;
32 	/* Implementation data */
33 	void *vt_data;
34 	/* Size of implementation data allocated */
35 	size_t vt_data_size;
36 	/* When resetting objects for reuse, this is set to allow 'vt' to be NULL */
37 	const NAL_SELECTOR_vtable *reset;
38 };
39 
40 /*****************************************/
41 /* Intermediaire selector implementation */
42 /*****************************************/
43 
dyn_on_create(NAL_SELECTOR * s)44 static int dyn_on_create(NAL_SELECTOR *s) { return 1; }
dyn_on_destroy(NAL_SELECTOR * s)45 static void dyn_on_destroy(NAL_SELECTOR *s) { }
dyn_on_reset(NAL_SELECTOR * s)46 static void dyn_on_reset(NAL_SELECTOR *s) { }
dyn_get_type(const NAL_SELECTOR * s)47 static NAL_SELECTOR_TYPE dyn_get_type(const NAL_SELECTOR *s) {
48 	return NAL_SELECTOR_TYPE_DYNAMIC; }
dyn_select(NAL_SELECTOR * s,unsigned long x,int y)49 static int dyn_select(NAL_SELECTOR *s, unsigned long x, int y) { return -1; }
dyn_num_objects(const NAL_SELECTOR * s)50 static unsigned int dyn_num_objects(const NAL_SELECTOR *s) { return 0; }
51 static const NAL_SELECTOR_vtable vtable_dyn = {
52 	0, /* vtdata_size */
53 	dyn_on_create,
54 	dyn_on_destroy,
55 	dyn_on_reset,
56 	NULL, /* pre_close */
57 	dyn_get_type,
58 	dyn_select,
59 	dyn_num_objects,
60 	NULL, /* add_listener - shouldn't be called */
61 	NULL, /* add_connection - shouldn't be called */
62 	NULL, /* del_listener - shouldn't be called */
63 	NULL, /* del_connection - shouldn't be called */
64 	NULL
65 };
66 
67 /****************************/
68 /* nal_internal.h functions */
69 /****************************/
70 
nal_selector_add_listener(NAL_SELECTOR * s,NAL_LISTENER * l)71 NAL_SELECTOR_TOKEN nal_selector_add_listener(NAL_SELECTOR *s, NAL_LISTENER *l)
72 {
73 	if(s->vt) return s->vt->add_listener(s, l);
74 	return NAL_SELECTOR_TOKEN_NULL;
75 }
76 
nal_selector_add_connection(NAL_SELECTOR * s,NAL_CONNECTION * c)77 NAL_SELECTOR_TOKEN nal_selector_add_connection(NAL_SELECTOR *s, NAL_CONNECTION *c)
78 {
79 	if(s->vt) return s->vt->add_connection(s, c);
80 	return NAL_SELECTOR_TOKEN_NULL;
81 }
82 
nal_selector_del_listener(NAL_SELECTOR * s,NAL_LISTENER * l,NAL_SELECTOR_TOKEN k)83 void nal_selector_del_listener(NAL_SELECTOR *s, NAL_LISTENER *l, NAL_SELECTOR_TOKEN k)
84 {
85 	if(s->vt) s->vt->del_listener(s, l, k);
86 }
87 
nal_selector_del_connection(NAL_SELECTOR * s,NAL_CONNECTION * c,NAL_SELECTOR_TOKEN k)88 void nal_selector_del_connection(NAL_SELECTOR *s, NAL_CONNECTION *c, NAL_SELECTOR_TOKEN k)
89 {
90 	if(s->vt) s->vt->del_connection(s, c, k);
91 }
92 
93 /*************************/
94 /* nal_devel.h functions */
95 /*************************/
96 
nal_selector_new(const NAL_SELECTOR_vtable * vtable)97 NAL_SELECTOR *nal_selector_new(const NAL_SELECTOR_vtable *vtable)
98 {
99 	NAL_SELECTOR *sel = SYS_malloc(NAL_SELECTOR, 1);
100 	if(!sel) goto err;
101 	if(vtable->vtdata_size) {
102 		sel->vt_data = SYS_malloc(unsigned char, vtable->vtdata_size);
103 		if(!sel->vt_data) goto err;
104 	} else
105 		sel->vt_data = NULL;
106 	sel->vt = vtable;
107 	sel->vt_data_size = vtable->vtdata_size;
108 	sel->reset = NULL;
109 	SYS_zero_n(unsigned char, sel->vt_data, vtable->vtdata_size);
110 	if(!vtable->on_create(sel)) goto err;
111 	return sel;
112 err:
113 	if(sel) {
114 		if(sel->vt_data) SYS_free(void, sel->vt_data);
115 		SYS_free(NAL_SELECTOR, sel);
116 	}
117 	return NULL;
118 }
119 
nal_selector_get_vtable(const NAL_SELECTOR * sel)120 const NAL_SELECTOR_vtable *nal_selector_get_vtable(const NAL_SELECTOR *sel)
121 {
122 	return sel->vt;
123 }
124 
nal_selector_get_vtdata(const NAL_SELECTOR * sel)125 void *nal_selector_get_vtdata(const NAL_SELECTOR *sel)
126 {
127 	return sel->vt_data;
128 }
129 
nal_selector_get_type(const NAL_SELECTOR * sel)130 NAL_SELECTOR_TYPE nal_selector_get_type(const NAL_SELECTOR *sel)
131 {
132 	if(!sel->vt) return NAL_SELECTOR_TYPE_ERROR;
133 	return sel->vt->get_type(sel);
134 }
135 
nal_selector_ctrl(NAL_SELECTOR * sel,int cmd,void * p)136 int nal_selector_ctrl(NAL_SELECTOR *sel, int cmd, void *p)
137 {
138 	if(sel->vt && sel->vt->ctrl)
139 		return sel->vt->ctrl(sel, cmd, p);
140 	return 0;
141 }
142 
nal_selector_dynamic_set(NAL_SELECTOR * s,const NAL_SELECTOR_vtable * vt)143 int nal_selector_dynamic_set(NAL_SELECTOR *s, const NAL_SELECTOR_vtable *vt) {
144 	assert(s->vt == &vtable_dyn);
145 	assert(s->vt_data == NULL);
146 	assert(s->vt_data_size == 0);
147 	assert(s->reset == NULL);
148 	if(s->vt != &vtable_dyn) return 0;
149 	if(vt->vtdata_size) {
150 		s->vt_data = SYS_malloc(unsigned char, vt->vtdata_size);
151 		if(!s->vt_data) return 0;
152 	}
153 	SYS_zero_n(unsigned char, s->vt_data, vt->vtdata_size);
154 	s->vt = vt;
155 	s->vt_data_size = vt->vtdata_size;
156 	if(!vt->on_create(s)) {
157 		SYS_free(void, s->vt_data);
158 		s->vt = &vtable_dyn;
159 		s->vt_data_size = 0;
160 		return 0;
161 	}
162 	return 1;
163 }
164 
165 /*******************/
166 /* nal.h functions */
167 /*******************/
168 
NAL_SELECTOR_new(void)169 NAL_SELECTOR *NAL_SELECTOR_new(void)
170 {
171 	return nal_selector_new(&vtable_dyn);
172 }
173 
NAL_SELECTOR_free(NAL_SELECTOR * sel)174 void NAL_SELECTOR_free(NAL_SELECTOR *sel)
175 {
176 	assert(sel->vt);
177 	if(sel->vt->pre_close) sel->vt->pre_close(sel);
178 	sel->vt->on_destroy(sel);
179 	if(sel->vt_data) SYS_free(void, sel->vt_data);
180 	SYS_free(NAL_SELECTOR, sel);
181 }
182 
NAL_SELECTOR_reset(NAL_SELECTOR * sel)183 void NAL_SELECTOR_reset(NAL_SELECTOR *sel)
184 {
185 	assert(sel->vt);
186 	if(sel->vt->pre_close) sel->vt->pre_close(sel);
187 	sel->vt->on_reset(sel);
188 }
189 
NAL_SELECTOR_select(NAL_SELECTOR * sel,unsigned long usec_timeout,int use_timeout)190 int NAL_SELECTOR_select(NAL_SELECTOR *sel, unsigned long usec_timeout,
191 			int use_timeout)
192 {
193 	assert(sel->vt);
194 	return sel->vt->select(sel, usec_timeout, use_timeout);
195 }
196 
NAL_SELECTOR_num_objects(const NAL_SELECTOR * sel)197 unsigned int NAL_SELECTOR_num_objects(const NAL_SELECTOR *sel)
198 {
199 	assert(sel->vt);
200 	return sel->vt->num_objects(sel);
201 }
202