00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include "event_int.h"
00028
00029 #include <stdlib.h>
00030 #include <string.h>
00031
00032 RCSTAG("@(#)$Id: event_gen_register.c,v 1.7 2005/12/18 00:15:11 klmitch Exp $");
00033
00040 struct generator {
00041 unsigned int gentype;
00042 ev_magic_t genmagic;
00043 size_t gensize;
00044 ev_freegen_t genrel;
00046 };
00047
00060 #define gd_init(gd, desc) \
00061 do { \
00062 ev_gendesc_t *_gd = (gd); \
00063 struct generator *_desc = (desc); \
00064 \
00065 _gd->gd_type = _desc->gentype; \
00066 _gd->gd_magic = _desc->genmagic; \
00067 _gd->gd_size = _desc->gensize; \
00068 _gd->gd_release = _desc->genrel; \
00069 \
00070 _gd->gd_active.gl_count = 0; \
00071 _gd->gd_active.gl_list = 0; \
00072 _gd->gd_free.gl_count = 0; \
00073 _gd->gd_free.gl_list = 0; \
00074 } while (0)
00075
00088 #define gens_link(ctx, gens) \
00089 do { \
00090 ev_ctx_t *_ctx = (ctx); \
00091 ev_gens_t *_gens = (gens); \
00092 if (_gens->gs_next) \
00093 _gens->gs_next->gs_prev = _gens; \
00094 if (_gens->gs_prev) \
00095 _gens->gs_prev->gs_next = _gens; \
00096 else \
00097 _ctx->ec_gens = _gens; \
00098 } while (0)
00099
00118 static ev_err_t
00119 gens_construct(ev_ctx_t *ctx, ev_gens_t *prev, ev_gens_t *next,
00120 struct generator *desc)
00121 {
00122 ev_gens_t *gens;
00123
00124 ev_trace();
00125
00126
00127 if (!(gens = (ev_gens_t *)malloc(sizeof(ev_gens_t))))
00128 ev_return(ENOMEM);
00129
00130
00131 gens->gs_next = next;
00132 gens->gs_prev = prev;
00133
00134 gens->gs_first = desc->gentype;
00135 gens->gs_count = 1;
00136
00137
00138 gd_init(&gens->gs_gens[0], desc);
00139
00140 if (desc->gentype > ctx->ec_maxgen)
00141 ctx->ec_maxgen = desc->gentype;
00142
00143
00144 gens_link(ctx, gens);
00145
00146 ev_return(0);
00147 }
00148
00166 static ev_err_t
00167 gens_extend(ev_ctx_t *ctx, ev_gens_t *gens, struct generator *desc)
00168 {
00169 ev_gendesc_t *gd;
00170
00171 ev_trace();
00172
00173 ev_assert(gens);
00174
00175
00176 if (!(gens = (ev_gens_t *)realloc(gens, sizeof(ev_gens_t) +
00177 sizeof(ev_gendesc_t) * gens->gs_count)))
00178 ev_return(ENOMEM);
00179
00180 if (gens->gs_first > desc->gentype) {
00181 memmove(&gens->gs_gens[1], &gens->gs_gens[0],
00182 sizeof(ev_gendesc_t) * gens->gs_count);
00183 gens->gs_first = desc->gentype;
00184 gd = &gens->gs_gens[0];
00185 } else
00186 gd = &gens->gs_gens[gens->gs_count];
00187
00188 gens->gs_count++;
00189
00190
00191 gd_init(gd, desc);
00192
00193 if (desc->gentype > ctx->ec_maxgen)
00194 ctx->ec_maxgen = desc->gentype;
00195
00196
00197 gens_link(ctx, gens);
00198
00199 ev_return(0);
00200 }
00201
00223 static ev_err_t
00224 gens_merge(ev_ctx_t *ctx, ev_gens_t *gens, struct generator *desc)
00225 {
00226 ev_gens_t *new;
00227
00228 ev_trace();
00229
00230 ev_assert(gens);
00231 ev_assert(gens->gs_next);
00232
00233
00234 if (!(new = (ev_gens_t *)malloc(sizeof(ev_gens_t) + sizeof(ev_gendesc_t) *
00235 (gens->gs_count + gens->gs_next->gs_count))))
00236 ev_return(ENOMEM);
00237
00238
00239 new->gs_next = gens->gs_next->gs_next;
00240 new->gs_prev = gens->gs_prev;
00241
00242 new->gs_first = gens->gs_first;
00243 new->gs_count = gens->gs_count + gens->gs_next->gs_count + 1;
00244
00245
00246 memcpy(&new->gs_gens[0], &gens->gs_gens[0],
00247 sizeof(ev_gendesc_t) * gens->gs_count);
00248
00249
00250 memcpy(&new->gs_gens[gens->gs_count + 1], &gens->gs_next->gs_gens[0],
00251 sizeof(ev_gendesc_t) * gens->gs_next->gs_count);
00252
00253
00254 gd_init(&new->gs_gens[gens->gs_count], desc);
00255
00256
00257 ev_assert(desc->gentype <= ctx->ec_maxgen);
00258
00259
00260 gens_link(ctx, new);
00261
00262
00263 free(gens->gs_next);
00264 free(gens);
00265
00266 ev_return(0);
00267 }
00268
00269 ev_err_t
00270 event_gen_register(ev_ctx_t *ctx, unsigned int gentype, ev_magic_t genmagic,
00271 size_t gensize, ev_freegen_t genrel)
00272 {
00273 ev_gens_t *gens, *last = 0;
00274 struct generator desc;
00275
00276 ev_init();
00277
00278 if (!ec_verify(ctx) || gentype == EGT_NONE || !genmagic ||
00279 gensize < sizeof(ev_genhdr_t))
00280 ev_return(EINVAL);
00281
00282 desc.gentype = gentype;
00283 desc.genmagic = genmagic;
00284 desc.gensize = gensize;
00285 desc.genrel = genrel;
00286
00287
00288 if (!ctx->ec_gens || gentype < ctx->ec_gens->gs_first - 1)
00289
00290 ev_return(gens_construct(ctx, 0, ctx->ec_gens, &desc));
00291
00292
00293 for (gens = ctx->ec_gens; gens; last = gens, gens = gens->gs_next) {
00294
00295 if (gentype >= gens->gs_first && gentype < gens->gs_first + gens->gs_count)
00296 ev_return(EV_ERR_DUPGEN);
00297
00298
00299 if (gentype >= gens->gs_first + gens->gs_count && gens->gs_next &&
00300 gentype < gens->gs_next->gs_first)
00301 break;
00302 }
00303
00304 ev_assert(gens || last);
00305
00306
00307 if (!gens && gentype != last->gs_first + last->gs_count)
00308 ev_return(gens_construct(ctx, last, 0, &desc));
00309 else if (!gens)
00310 gens = last;
00311
00312
00313 if (gentype == gens->gs_first + gens->gs_count ||
00314 (gens->gs_next && gentype == gens->gs_next->gs_first - 1)) {
00315
00316 if (gentype == gens->gs_first + gens->gs_count &&
00317 gens->gs_next && gentype == gens->gs_next->gs_first - 1)
00318 ev_return(gens_merge(ctx, gens, &desc));
00319
00320
00321 ev_return(gens_extend(ctx, ((gentype == gens->gs_first + gens->gs_count) ?
00322 gens : gens->gs_next), &desc));
00323 }
00324
00325
00326 ev_return(gens_construct(ctx, gens, gens->gs_next, &desc));
00327 }