module-context.h revision 793f2c5e5bf9b4fcdfbedff89e6d1f26aebfd604
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen This is a bit complex to use, but it prevents using wrong module IDs
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen in module_contexts arrays.
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen The main structure is implemented like this:
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct STRUCT_NAME_module_register {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int id;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union STRUCT_NAME_module_context {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct STRUCT_NAME_module_register *reg;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen // it's allowed to have some structure here so it won't waste space.
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen // for example: struct STRUCT_NAME_vfuncs super;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct STRUCT_NAME {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ARRAY_DEFINE(module_contexts, union STRUCT_NAME_module_context *);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen extern struct STRUCT_NAME_module_register STRUCT_NAME_module_register;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen The usage in modules goes like:
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen static MODULE_CONTEXT_DEFINE(mymodule_STRUCT_NAME_module,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen &STRUCT_NAME_module_register);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mymodule_STRUCT_NAME {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union STRUCT_NAME_module_context module_ctx;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen // module-specific data
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mymodule_STRUCT_NAME *ctx = i_new(...);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET(obj, mymodule_STRUCT_NAME_module, ctx);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mymodule_STRUCT_NAME *ctx =
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT(obj, mymodule_STRUCT_NAME_module);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(OBJ_REGISTER(obj), (id_ctx).reg)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen (*((void **)array_idx_modifiable(&(obj)->module_contexts, \
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#define MODULE_CONTEXT_DEFINE_INIT(_name, _reg) \
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_DEFINE(_name, _reg) = MODULE_CONTEXT_INIT(_reg)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic inline unsigned int module_get_context_id(struct module_context_id *id)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#define MODULE_CONTEXT_SET_FULL(obj, id_ctx, ctx, module_ctx) STMT_START { \
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(module_ctx, \
793f2c5e5bf9b4fcdfbedff89e6d1f26aebfd604Timo Sirainen module_get_context_id(&(id_ctx).id), &_module_tmp); \
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#define MODULE_CONTEXT_SET(obj, id_ctx, context) \
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET_FULL(obj, id_ctx, context, &(context)->module_ctx)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#define MODULE_CONTEXT_SET_SELF(obj, id_ctx, context) \
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET_FULL(obj, id_ctx, context, context)