00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _CFG_STRUCT_H
00030 #define _CFG_STRUCT_H
00031
00032 #include "../str.h"
00033 #include "../atomic_ops.h"
00034 #include "../mem/shm_mem.h"
00035 #include "../locking.h"
00036 #include "../compiler_opt.h"
00037 #include "../bit_test.h"
00038 #include "cfg.h"
00039
00041 #define CFG_MAX_VAR_NUM 256
00042
00044 #define cfg_var_shmized 1U
00045
00050 typedef struct _cfg_add_var {
00051 struct _cfg_add_var *next;
00052 unsigned int type;
00054 union {
00055 char *ch;
00056 str s;
00057 int i;
00058 } val;
00059 unsigned int group_id;
00060 int name_len;
00064 char name[1];
00065 } cfg_add_var_t;
00066
00068 typedef struct _cfg_mapping {
00069 cfg_def_t *def;
00070 int name_len;
00072
00073 int pos;
00074 int offset;
00075 unsigned int flag;
00076 } cfg_mapping_t;
00077
00079 enum { CFG_GROUP_UNKNOWN = 0, CFG_GROUP_DYNAMIC, CFG_GROUP_STATIC };
00080
00082 typedef struct _cfg_group {
00083 int num;
00084 cfg_mapping_t *mapping;
00086 char *vars;
00089 cfg_add_var_t *add_var;
00092 int size;
00094 int meta_offset;
00096 int var_offset;
00098 void **handle;
00102 void *orig_handle;
00107 unsigned char dynamic;
00109 struct _cfg_group *next;
00110 int name_len;
00111 char name[1];
00112 } cfg_group_t;
00113
00116 typedef struct _cfg_group_inst {
00117 unsigned int id;
00118 unsigned int set[CFG_MAX_VAR_NUM/(sizeof(int)*8)];
00122 unsigned char vars[1];
00123 } cfg_group_inst_t;
00124
00129 typedef struct _cfg_group_meta {
00130 int num;
00131 cfg_group_inst_t *array;
00132 } cfg_group_meta_t;
00133
00135 typedef struct _cfg_block {
00136 atomic_t refcnt;
00139 unsigned char vars[1];
00140 } cfg_block_t;
00141
00148 typedef struct _cfg_child_cb {
00149 atomic_t refcnt;
00151 atomic_t cb_count;
00157 str gname, name;
00158 cfg_on_set_child cb;
00159 void **replaced;
00165 struct _cfg_child_cb *next;
00166 } cfg_child_cb_t;
00167
00168 extern cfg_group_t *cfg_group;
00169 extern cfg_block_t **cfg_global;
00170 extern cfg_block_t *cfg_local;
00171 extern int cfg_block_size;
00172 extern gen_lock_t *cfg_global_lock;
00173 extern gen_lock_t *cfg_writer_lock;
00174 extern int cfg_shmized;
00175 extern cfg_child_cb_t **cfg_child_cb_first;
00176 extern cfg_child_cb_t **cfg_child_cb_last;
00177 extern cfg_child_cb_t *cfg_child_cb;
00178 extern int cfg_ginst_count;
00179
00180
00181
00182 #define CFG_NO_CHILD_CBS ((void*)(long)(-1))
00183
00184
00185 #define CFG_VAR_TYPE(var) CFG_VAR_MASK((var)->def->type)
00186 #define CFG_INPUT_TYPE(var) CFG_INPUT_MASK((var)->def->type)
00187
00188
00189 #define CFG_GROUP_META(block, group) \
00190 ((cfg_group_meta_t *)((block)->vars + (group)->meta_offset))
00191
00192
00193 #define CFG_GROUP_DATA(block, group) \
00194 ((unsigned char *)((block)->vars + (group)->var_offset))
00195
00196
00197
00198 #define CFG_VAR_TEST(group_inst, var) \
00199 bit_test((var)->pos % (sizeof(int)*8), (group_inst)->set + (var)->pos/(sizeof(int)*8))
00200
00201
00202
00203 #define CFG_VAR_TEST_AND_SET(group_inst, var) \
00204 bit_test_and_set((var)->pos % (sizeof(int)*8), (group_inst)->set + (var)->pos/(sizeof(int)*8))
00205
00206
00207
00208 #define CFG_VAR_TEST_AND_RESET(group_inst, var) \
00209 bit_test_and_reset((var)->pos % (sizeof(int)*8), (group_inst)->set + (var)->pos/(sizeof(int)*8))
00210
00211
00212
00213 #define CFG_HANDLE_TO_GINST(h) \
00214 ( (((unsigned char*)(h) < cfg_local->vars) \
00215 || ((unsigned char*)(h) > cfg_local->vars + cfg_block_size) \
00216 ) ? \
00217 (cfg_group_inst_t*)((char*)(h) - (unsigned long)&((cfg_group_inst_t *)0)->vars) \
00218 : NULL )
00219
00220
00221 int sr_cfg_init(void);
00222
00223
00224 void cfg_destroy(void);
00225
00226
00227
00228
00229
00230
00231 void cfg_register_child(int num);
00232
00233
00234
00235
00236
00237 int cfg_child_init(void);
00238
00239
00240
00241
00242
00243 int cfg_late_child_init(void);
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 int cfg_child_no_cb_init(void);
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 void cfg_child_destroy(void);
00264
00265
00266 cfg_group_t *cfg_new_group(char *name, int name_len,
00267 int num, cfg_mapping_t *mapping,
00268 char *vars, int size, void **handle);
00269
00270
00271 void cfg_set_group(cfg_group_t *group,
00272 int num, cfg_mapping_t *mapping,
00273 char *vars, int size, void **handle);
00274
00275
00276 int cfg_shmize(void);
00277
00278
00279 static inline void cfg_child_cb_free_item(cfg_child_cb_t *cb)
00280 {
00281 int i;
00282
00283
00284 if (cb->replaced) {
00285 for (i=0; cb->replaced[i]; i++)
00286 shm_free(cb->replaced[i]);
00287 shm_free(cb->replaced);
00288 }
00289 shm_free(cb);
00290 }
00291
00292 #define cfg_block_free(block) \
00293 shm_free(block)
00294
00295
00296
00297
00298
00299
00300
00301
00302 void cfg_move_handle(cfg_group_t *group, cfg_group_inst_t *src_ginst, cfg_group_inst_t *dst_ginst);
00303
00304
00305
00306
00307 #define CFG_LOCK() lock_get(cfg_global_lock);
00308 #define CFG_UNLOCK() lock_release(cfg_global_lock);
00309
00310
00311
00312
00313 #define CFG_WRITER_LOCK() lock_get(cfg_writer_lock);
00314 #define CFG_WRITER_UNLOCK() lock_release(cfg_writer_lock);
00315
00316
00317 #define CFG_REF(block) \
00318 atomic_inc(&(block)->refcnt)
00319
00320 #define CFG_UNREF(block) \
00321 do { \
00322 if (atomic_dec_and_test(&(block)->refcnt)) \
00323 cfg_block_free(block); \
00324 } while(0)
00325
00326
00327
00328
00329
00330
00331
00332 static inline void cfg_update_local(int no_cbs)
00333 {
00334 cfg_group_t *group;
00335 cfg_child_cb_t *last_cb;
00336 cfg_child_cb_t *prev_cb;
00337
00338 if (cfg_local) CFG_UNREF(cfg_local);
00339 CFG_LOCK();
00340 CFG_REF(*cfg_global);
00341 cfg_local = *cfg_global;
00342
00343 last_cb = *cfg_child_cb_last;
00344
00345
00346
00347
00348
00349
00350 CFG_UNLOCK();
00351
00352
00353 for ( group = cfg_group;
00354 group;
00355 group = group->next
00356 )
00357 *(group->handle) = CFG_GROUP_DATA(cfg_local, group);
00358
00359 if (unlikely(cfg_child_cb==CFG_NO_CHILD_CBS || no_cbs))
00360 return;
00361
00362 while (cfg_child_cb != last_cb) {
00363 prev_cb = cfg_child_cb;
00364 cfg_child_cb = cfg_child_cb->next;
00365 atomic_inc(&cfg_child_cb->refcnt);
00366 if (atomic_dec_and_test(&prev_cb->refcnt)) {
00367
00368
00369
00370
00371 CFG_LOCK();
00372 if (*cfg_child_cb_first == prev_cb) {
00373
00374 *cfg_child_cb_first = cfg_child_cb;
00375 CFG_UNLOCK();
00376 cfg_child_cb_free_item(prev_cb);
00377 } else {
00378 CFG_UNLOCK();
00379 }
00380 }
00381 if (cfg_child_cb->cb
00382 && (atomic_add(&cfg_child_cb->cb_count, -1) >= 0)
00383
00384 )
00385
00386 cfg_child_cb->cb(&cfg_child_cb->gname, &cfg_child_cb->name);
00387
00388 }
00389 }
00390
00391
00392 static inline void cfg_reset_handles(void)
00393 {
00394 cfg_group_t *group;
00395
00396 if (!cfg_local)
00397 return;
00398
00399 for ( group = cfg_group;
00400 group && cfg_ginst_count;
00401
00402
00403 group = group->next
00404 ) {
00405 if (((unsigned char*)*(group->handle) < cfg_local->vars)
00406 || ((unsigned char*)*(group->handle) > cfg_local->vars + cfg_block_size)
00407 )
00408 cfg_move_handle(group,
00409 CFG_HANDLE_TO_GINST(*(group->handle)),
00410 NULL);
00411 }
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421 #define cfg_update() \
00422 do { \
00423 if (unlikely(cfg_ginst_count)) \
00424 cfg_reset_handles(); \
00425 if (unlikely(cfg_local != *cfg_global)) \
00426 cfg_update_local(0); \
00427 } while(0)
00428
00429
00430
00431
00432
00433 #define cfg_update_no_cbs() \
00434 do { \
00435 if (unlikely(cfg_local != *cfg_global)) \
00436 cfg_update_local(1); \
00437 } while(0)
00438
00439
00440
00441
00442 #define cfg_reset_all() \
00443 do { \
00444 if (unlikely(cfg_ginst_count)) \
00445 cfg_reset_handles(); \
00446 } while(0)
00447
00448
00449
00450 cfg_group_t *cfg_lookup_group(char *name, int len);
00451
00452
00453 int cfg_lookup_var(str *gname, str *vname,
00454 cfg_group_t **group, cfg_mapping_t **var);
00455
00456
00457 cfg_mapping_t *cfg_lookup_var2(cfg_group_t *group, char *name, int len);
00458
00459
00460
00461
00462 cfg_block_t *cfg_clone_global(void);
00463
00464
00465 cfg_group_inst_t *cfg_clone_array(cfg_group_meta_t *meta, cfg_group_t *group);
00466
00467
00468
00469 cfg_group_inst_t *cfg_extend_array(cfg_group_meta_t *meta, cfg_group_t *group,
00470 unsigned int group_id,
00471 cfg_group_inst_t **new_group);
00472
00473
00474
00475
00476 int cfg_collapse_array(cfg_group_meta_t *meta, cfg_group_t *group,
00477 cfg_group_inst_t *inst,
00478 cfg_group_inst_t **_new_array);
00479
00480
00481 int cfg_clone_str(str *src, str *dst);
00482
00483
00484 cfg_group_inst_t *cfg_find_group(cfg_group_meta_t *meta, int group_size, unsigned int group_id);
00485
00486
00487
00488
00489
00490
00491 void cfg_install_child_cb(cfg_child_cb_t *cb_first, cfg_child_cb_t *cb_last);
00492
00493
00494
00495
00496
00497
00498
00499
00500 void cfg_install_global(cfg_block_t *block, void **replaced,
00501 cfg_child_cb_t *cb_first, cfg_child_cb_t *cb_last);
00502
00503
00504 cfg_child_cb_t *cfg_child_cb_new(str *gname, str *name,
00505 cfg_on_set_child cb,
00506 unsigned int type);
00507
00508
00509 void cfg_child_cb_free_list(cfg_child_cb_t *child_cb_first);
00510
00511
00512
00513
00514
00515
00516
00517 int new_add_var(str *group_name, unsigned int group_id, str *var_name,
00518 void *val, unsigned int type);
00519
00520
00521 int cfg_select(cfg_group_t *group, unsigned int id);
00522
00523
00524 int cfg_reset(cfg_group_t *group);
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 int cfg_select_first(cfg_group_t *group);
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 int cfg_select_next(cfg_group_t *group);
00546
00547
00548
00549
00550
00551 void cfg_main_set_local(void);
00552
00553
00554
00555
00556 void cfg_main_reset_local(void);
00557
00558 #endif