[dovecot-cvs] dovecot/src/lib Makefile.am, 1.71, 1.72 module-context.h, NONE, 1.1
tss at dovecot.org
tss at dovecot.org
Thu Mar 29 14:51:35 EEST 2007
Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv16171/lib
Modified Files:
Makefile.am
Added Files:
module-context.h
Log Message:
Better type safety to module_contexts arrays. Already fixed some bugs.
Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/Makefile.am,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -d -r1.71 -r1.72
--- Makefile.am 18 Mar 2007 01:57:11 -0000 1.71
+++ Makefile.am 29 Mar 2007 11:51:32 -0000 1.72
@@ -135,6 +135,7 @@
mempool.h \
mkdir-parents.h \
mmap-util.h \
+ module-context.h \
module-dir.h \
mountpoint.h \
network.h \
--- NEW FILE: module-context.h ---
#ifndef __MODULE_CONTEXT_H
#define __MODULE_CONTEXT_H
/*
This is a bit complex to use, but it prevents using wrong module IDs
in module_contexts arrays.
---------
The main structure is implemented like this:
struct STRUCT_NAME_module_register {
unsigned int id;
};
union STRUCT_NAME_module_context {
struct STRUCT_NAME_module_register *reg;
// it's allowed to have some structure here so it won't waste space.
// for example: struct STRUCT_NAME_vfuncs super;
};
struct STRUCT_NAME {
ARRAY_DEFINE(module_contexts, union STRUCT_NAME_module_context *);
};
extern struct STRUCT_NAME_module_register STRUCT_NAME_module_register;
---------
The usage in modules goes like:
static MODULE_CONTEXT_DEFINE(mymodule_STRUCT_NAME_module,
&STRUCT_NAME_module_register);
struct mymodule_STRUCT_NAME {
union STRUCT_NAME_module_context module_ctx;
// module-specific data
};
struct mymodule_STRUCT_NAME *ctx = i_new(...);
MODULE_CONTEXT_SET(obj, mymodule_STRUCT_NAME_module, ctx);
struct mymodule_STRUCT_NAME *ctx =
MODULE_CONTEXT(obj, mymodule_STRUCT_NAME_module);
*/
#define OBJ_REGISTER(obj) \
((**(obj)->module_contexts.v)->reg)
#define OBJ_REGISTER_COMPATIBLE(obj, id_ctx) \
COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(OBJ_REGISTER(obj), (id_ctx).reg)
#define MODULE_CONTEXT(obj, id_ctx) \
(*((void **)array_idx_modifiable(&(obj)->module_contexts, \
(id_ctx).id.module_id) + \
OBJ_REGISTER_COMPATIBLE(obj, id_ctx)))
#ifdef HAVE_TYPEOF
# define MODULE_CONTEXT_DEFINE(_name, _reg) \
struct _name { \
struct module_context_id id; \
typeof(_reg) reg; \
} _name
# define MODULE_CONTEXT_INIT(_reg) \
{ { &(_reg)->id, 0, FALSE }, NULL }
#else
# define MODULE_CONTEXT_DEFINE(_name, _reg) \
struct _name { \
struct module_context_id id; \
} _name
# define MODULE_CONTEXT_INIT(_reg) \
{ { &(_reg)->id, 0, FALSE } }
#endif
#define MODULE_CONTEXT_DEFINE_INIT(_name, _reg) \
MODULE_CONTEXT_DEFINE(_name, _reg) = MODULE_CONTEXT_INIT(_reg)
struct module_context_id {
unsigned int *module_id_register;
unsigned int module_id;
bool module_id_set;
};
static inline unsigned int module_get_context_id(struct module_context_id *id)
{
if (!id->module_id_set) {
id->module_id = *id->module_id_register;
id->module_id_set = TRUE;
*id->module_id_register += 1;
}
return id->module_id;
}
#define MODULE_CONTEXT_SET_FULL(obj, id_ctx, ctx, module_ctx) STMT_START { \
void *_module_tmp = ctx + \
COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(module_ctx, \
(**(obj)->module_contexts.v)) + \
OBJ_REGISTER_COMPATIBLE(obj, id_ctx); \
array_idx_set(&(obj)->module_contexts, \
module_get_context_id(&(id_ctx).id), (void *)&_module_tmp); \
} STMT_END
#define MODULE_CONTEXT_SET(obj, id_ctx, context) \
MODULE_CONTEXT_SET_FULL(obj, id_ctx, context, &(context)->module_ctx)
#define MODULE_CONTEXT_SET_SELF(obj, id_ctx, context) \
MODULE_CONTEXT_SET_FULL(obj, id_ctx, context, context)
#define MODULE_CONTEXT_UNSET(obj, id_ctx) \
array_idx_clear(&(obj)->module_contexts, (id_ctx).id.module_id)
#endif
More information about the dovecot-cvs
mailing list