~ubuntu-branches/ubuntu/wily/dovecot/wily-proposed

« back to all changes in this revision

Viewing changes to src/lib/module-context.h

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2008-08-02 14:00:15 UTC
  • mto: (1.11.1 upstream) (4.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20080802140015-zbmjsgoodeyc9z4s
Tags: upstream-1.1.2
ImportĀ upstreamĀ versionĀ 1.1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef MODULE_CONTEXT_H
 
2
#define MODULE_CONTEXT_H
 
3
 
 
4
/*
 
5
   This is a bit complex to use, but it prevents using wrong module IDs
 
6
   in module_contexts arrays.
 
7
 
 
8
   ---------
 
9
   The main structure is implemented like this:
 
10
 
 
11
   struct STRUCT_NAME_module_register {
 
12
           unsigned int id;
 
13
   };
 
14
   union STRUCT_NAME_module_context {
 
15
           struct STRUCT_NAME_module_register *reg;
 
16
           // it's allowed to have some structure here so it won't waste space.
 
17
           // for example: struct STRUCT_NAME_vfuncs super;
 
18
   };
 
19
   struct STRUCT_NAME {
 
20
        ARRAY_DEFINE(module_contexts, union STRUCT_NAME_module_context *);
 
21
   };
 
22
   extern struct STRUCT_NAME_module_register STRUCT_NAME_module_register;
 
23
 
 
24
   ---------
 
25
   The usage in modules goes like:
 
26
 
 
27
   static MODULE_CONTEXT_DEFINE(mymodule_STRUCT_NAME_module,
 
28
                                &STRUCT_NAME_module_register);
 
29
   struct mymodule_STRUCT_NAME {
 
30
        union STRUCT_NAME_module_context module_ctx;
 
31
        // module-specific data
 
32
   };
 
33
 
 
34
   struct mymodule_STRUCT_NAME *ctx = i_new(...);
 
35
   MODULE_CONTEXT_SET(obj, mymodule_STRUCT_NAME_module, ctx);
 
36
 
 
37
   struct mymodule_STRUCT_NAME *ctx =
 
38
        MODULE_CONTEXT(obj, mymodule_STRUCT_NAME_module);
 
39
*/
 
40
 
 
41
#define OBJ_REGISTER(obj) \
 
42
        ((**(obj)->module_contexts.v)->reg)
 
43
#define OBJ_REGISTER_COMPATIBLE(obj, id_ctx) \
 
44
        COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(OBJ_REGISTER(obj), (id_ctx).reg)
 
45
 
 
46
#define MODULE_CONTEXT(obj, id_ctx) \
 
47
        (*((void **)array_idx_modifiable(&(obj)->module_contexts, \
 
48
                                        (id_ctx).id.module_id) + \
 
49
         OBJ_REGISTER_COMPATIBLE(obj, id_ctx)))
 
50
 
 
51
#ifdef HAVE_TYPEOF
 
52
#  define MODULE_CONTEXT_DEFINE(_name, _reg) \
 
53
        struct _name { \
 
54
                struct module_context_id id; \
 
55
                typeof(_reg) reg; \
 
56
        } _name
 
57
#  define MODULE_CONTEXT_INIT(_reg) \
 
58
        { { &(_reg)->id, 0, FALSE }, NULL }
 
59
#else
 
60
#  define MODULE_CONTEXT_DEFINE(_name, _reg) \
 
61
        struct _name { \
 
62
                struct module_context_id id; \
 
63
        } _name
 
64
#  define MODULE_CONTEXT_INIT(_reg) \
 
65
        { { &(_reg)->id, 0, FALSE } }
 
66
#endif
 
67
 
 
68
#define MODULE_CONTEXT_DEFINE_INIT(_name, _reg) \
 
69
        MODULE_CONTEXT_DEFINE(_name, _reg) = MODULE_CONTEXT_INIT(_reg)
 
70
 
 
71
struct module_context_id {
 
72
        unsigned int *module_id_register;
 
73
        unsigned int module_id;
 
74
        bool module_id_set;
 
75
};
 
76
 
 
77
static inline unsigned int module_get_context_id(struct module_context_id *id)
 
78
{
 
79
        if (!id->module_id_set) {
 
80
                id->module_id = *id->module_id_register;
 
81
                id->module_id_set = TRUE;
 
82
                *id->module_id_register += 1;
 
83
        }
 
84
        return id->module_id;
 
85
}
 
86
 
 
87
#define MODULE_CONTEXT_SET_FULL(obj, id_ctx, ctx, module_ctx) STMT_START { \
 
88
        void *_module_tmp = ctx + \
 
89
                COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(module_ctx, \
 
90
                        (**(obj)->module_contexts.v)) + \
 
91
                OBJ_REGISTER_COMPATIBLE(obj, id_ctx); \
 
92
        array_idx_set_i(&(obj)->module_contexts.arr, \
 
93
                module_get_context_id(&(id_ctx).id), &_module_tmp); \
 
94
        } STMT_END
 
95
 
 
96
#define MODULE_CONTEXT_SET(obj, id_ctx, context) \
 
97
        MODULE_CONTEXT_SET_FULL(obj, id_ctx, context, &(context)->module_ctx)
 
98
#define MODULE_CONTEXT_SET_SELF(obj, id_ctx, context) \
 
99
        MODULE_CONTEXT_SET_FULL(obj, id_ctx, context, context)
 
100
 
 
101
#define MODULE_CONTEXT_UNSET(obj, id_ctx) \
 
102
        array_idx_clear(&(obj)->module_contexts, (id_ctx).id.module_id)
 
103
 
 
104
#endif