redis_module_ext/
export.rs1use std::ffi::c_int;
2
3use redis_module::raw;
4
5use crate::RedisModule;
6
7#[macro_export]
8macro_rules! export_redis_module {
9 ($module:ty) => {
10 const _: () = {
11 #[global_allocator]
13 static REDIS_MODULE_ALLOCATOR: $crate::redis::alloc::RedisAlloc = $crate::redis::alloc::RedisAlloc;
14
15 #[unsafe(no_mangle)]
16 #[allow(non_snake_case, unsafe_op_in_unsafe_fn)]
17 pub unsafe extern "C" fn RedisModule_OnLoad(
18 ctx: *mut $crate::raw::RedisModuleCtx,
19 argv: *mut *mut $crate::raw::RedisModuleString,
20 argc: std::os::raw::c_int,
21 ) -> std::os::raw::c_int {
22 unsafe { $crate::export::on_load::<$module>(ctx, argv, argc) }
23 }
24
25 #[unsafe(no_mangle)]
26 #[allow(non_snake_case, unsafe_op_in_unsafe_fn)]
27 pub extern "C" fn RedisModule_OnUnload(ctx: *mut $crate::raw::RedisModuleCtx) -> std::os::raw::c_int {
28 unsafe { $crate::export::on_unload::<$module>(ctx) }
29 }
30 };
31 };
32}
33
34pub unsafe fn on_load<M: RedisModule>(
38 ctx: *mut raw::RedisModuleCtx,
39 _: *mut *mut raw::RedisModuleString,
40 _: std::os::raw::c_int,
41) -> std::os::raw::c_int {
42 let name = M::name();
43 let version = M::version();
44
45 let result = unsafe { raw::Export_RedisModule_Init(ctx, name.as_ptr(), version, raw::REDISMODULE_APIVER_1 as c_int) };
46
47 if result == raw::Status::Err as c_int {
48 return raw::Status::Err as c_int;
49 }
50
51 let context = redis_module::Context::new(ctx);
52 let _ = redis_module::MODULE_CONTEXT.set_context(&context);
53
54 if !M::register_data_types(&context) {
55 return raw::Status::Err as c_int;
56 }
57
58 if let Err(e) = M::register_commands(&context) {
59 context.log_warning(&e.to_string());
60 }
61
62 if let Err(e) = redis_module::defrag::register_defrag_functions(&context) {
63 context.log_warning(&e.to_string());
64 return raw::Status::Err as c_int;
65 }
66
67 extern "C" fn __info_func(ctx: *mut raw::RedisModuleInfoCtx, for_crash_report: i32) {
68 redis_module::basic_info_command_handler(&redis_module::InfoContext::new(ctx), for_crash_report == 1);
69 }
70
71 raw::register_info_function(ctx, Some(__info_func));
72
73 if let Err(e) = redis_module::server_events::register_server_events(&context) {
74 context.log_warning(&e.to_string());
75 return raw::Status::Err as c_int;
76 }
77
78 if let Err(err) = M::init_fn(&context) {
79 context.log_warning(&err.to_string());
80 return raw::Status::Err as c_int;
81 }
82
83 raw::Status::Ok as c_int
84}
85
86pub unsafe fn on_unload<M: RedisModule>(ctx: *mut raw::RedisModuleCtx) -> std::os::raw::c_int {
90 let context = redis_module::Context::new(ctx);
91
92 if let Err(err) = M::deinit_fn(&context) {
93 context.log_warning(&err.to_string());
94 return raw::Status::Err as c_int;
95 }
96
97 raw::Status::Ok as c_int
98}