Skip to content

Commit 3ce2351

Browse files
author
Meir Shpilraien (Spielrein)
authored
Changed post notification job to recieve FnOnce. (#329)
Redis promise that the callback will be called exactly once so we can use FnOnce instead of Fn and have a better flexibility on the callback implementation (for example, the callback will be able to pass ownership of captured variables).
1 parent 82c4753 commit 3ce2351

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

src/context/mod.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,8 @@ impl Context {
709709
/// as a logical bug that need to be fixed in the module, an attempt to protect against
710710
/// infinite loops by halting the execution could result in violation of the feature correctness
711711
/// and so Redis will make no attempt to protect the module from infinite loops.
712-
pub fn add_post_notification_job<F: Fn(&Context)>(&self, callback: F) -> Status {
713-
let callback = Box::into_raw(Box::new(callback));
712+
pub fn add_post_notification_job<F: FnOnce(&Context)>(&self, callback: F) -> Status {
713+
let callback = Box::into_raw(Box::new(Some(callback)));
714714
unsafe {
715715
RedisModule_AddPostNotificationJob(
716716
self.ctx,
@@ -724,17 +724,27 @@ impl Context {
724724
);
725725
}
726726

727-
extern "C" fn post_notification_job_free_callback<F: Fn(&Context)>(pd: *mut c_void) {
728-
unsafe { Box::from_raw(pd as *mut F) };
727+
extern "C" fn post_notification_job_free_callback<F: FnOnce(&Context)>(pd: *mut c_void) {
728+
unsafe { Box::from_raw(pd as *mut Option<F>) };
729729
}
730730

731-
extern "C" fn post_notification_job<F: Fn(&Context)>(
731+
extern "C" fn post_notification_job<F: FnOnce(&Context)>(
732732
ctx: *mut raw::RedisModuleCtx,
733733
pd: *mut c_void,
734734
) {
735-
let callback = unsafe { &*(pd as *mut F) };
735+
let callback = unsafe { &mut *(pd as *mut Option<F>) };
736736
let ctx = Context::new(ctx);
737-
callback(&ctx);
737+
callback.take().map_or_else(
738+
|| {
739+
ctx.log(
740+
RedisLogLevel::Warning,
741+
"Got a None callback on post notification job.",
742+
)
743+
},
744+
|callback| {
745+
callback(&ctx);
746+
},
747+
);
738748
}
739749

740750
unsafe impl RedisLockIndicator for Context {}

0 commit comments

Comments
 (0)