}
if (free_reg == NULL) {
+ struct tevent_immediate *im = NULL;
+
+ im = tevent_create_immediate(ctx);
+ if (im == NULL) {
+ return false;
+ }
+
tmp = talloc_realloc(ctx, ctx->event_contexts,
struct messaging_registered_ev,
num_event_contexts+1);
ctx->event_contexts = tmp;
free_reg = &ctx->event_contexts[num_event_contexts];
+ free_reg->im = talloc_move(ctx->event_contexts, &im);
}
- *free_reg = (struct messaging_registered_ev) { .ev = ev, .refcount = 1 };
+ /*
+ * free_reg->im might be cached
+ */
+ free_reg->ev = ev;
+ free_reg->refcount = 1;
return true;
}
reg->refcount -= 1;
if (reg->refcount == 0) {
+ /*
+ * The primary event context
+ * is never unregistered using
+ * messaging_deregister_event_context()
+ * it's only registered using
+ * messaging_register_event_context().
+ */
+ SMB_ASSERT(ev != ctx->event_ctx);
+ SMB_ASSERT(reg->ev != ctx->event_ctx);
+
/*
* Not strictly necessary, just
* paranoia
/*
* Do not talloc_free(reg->im),
* recycle immediates events.
+ *
+ * We just invalidate it using
+ * the primary event context,
+ * which is never unregistered.
*/
+ tevent_schedule_immediate(reg->im,
+ ctx->event_ctx,
+ NULL, NULL);
}
return true;
}
continue;
}
- if (reg->im == NULL) {
- reg->im = tevent_create_immediate(
- ctx->event_contexts);
- }
- if (reg->im == NULL) {
- DBG_WARNING("Could not create immediate\n");
- continue;
- }
-
/*
* We depend on schedule_immediate to work
* multiple times. Might be a bit inefficient,
* alternatively would be to track whether the
* immediate has already been scheduled. For
* now, avoid that complexity here.
+ *
+ * reg->ev and ctx->event_ctx can't
+ * be wrapper tevent_context pointers
+ * so we don't need to use
+ * tevent_context_same_loop().
*/
if (reg->ev == ctx->event_ctx) {
sec_init();
- lck_path = lock_path("msg.lock");
+ if (tevent_context_is_wrapper(ev)) {
+ /* This is really a programmer error! */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ lck_path = lock_path(talloc_tos(), "msg.lock");
if (lck_path == NULL) {
return NT_STATUS_NO_MEMORY;
}
return ctx;
}
-NTSTATUS messaging_init_client(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct messaging_context **pmsg_ctx)
-{
- return messaging_init_internal(mem_ctx,
- ev,
- pmsg_ctx);
-}
-
struct server_id messaging_server_id(const struct messaging_context *msg_ctx)
{
return msg_ctx->id;
.pid = getpid(), .vnn = msg_ctx->id.vnn
};
- lck_path = lock_path("msg.lock");
+ lck_path = lock_path(talloc_tos(), "msg.lock");
if (lck_path == NULL) {
return NT_STATUS_NO_MEMORY;
}
state->filter = filter;
state->private_data = private_data;
+ if (tevent_context_is_wrapper(ev)) {
+ /* This is really a programmer error! */
+ DBG_ERR("Wrapper tevent context doesn't use main context.\n");
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
+ }
+
/*
* We have to defer the callback here, as we might be called from
* within a different tevent_context than state->ev
bool consumed;
size_t i;
+ /*
+ * ev and msg_ctx->event_ctx can't be wrapper tevent_context pointers
+ * so we don't need to use tevent_context_same_loop().
+ */
+
if (ev == msg_ctx->event_ctx) {
consumed = messaging_dispatch_classic(msg_ctx, rec);
if (consumed) {