const TDB_DATA *dbufs, int num_dbufs,
int flags);
static NTSTATUS dbwrap_watched_delete(struct db_record *rec);
-static void dbwrap_watched_watch_skip_alerting(struct db_record *rec);
static int db_watched_record_destructor(struct db_watched_record *wrec);
static void db_watched_record_init(struct db_context *db,
return db;
}
-static uint64_t dbwrap_watched_watch_add_instance(struct db_record *rec)
+uint64_t dbwrap_watched_watch_add_instance(struct db_record *rec)
{
struct db_watched_record *wrec = db_record_get_watched_record(rec);
static uint64_t global_instance = 1;
return wrec->added.instance;
}
-static void dbwrap_watched_watch_remove_instance(struct db_record *rec, uint64_t instance)
+void dbwrap_watched_watch_remove_instance(struct db_record *rec, uint64_t instance)
{
struct db_watched_record *wrec = db_record_get_watched_record(rec);
struct dbwrap_watcher clear_watcher = {
return;
}
-static void dbwrap_watched_watch_skip_alerting(struct db_record *rec)
+void dbwrap_watched_watch_skip_alerting(struct db_record *rec)
{
struct db_watched_record *wrec = db_record_get_watched_record(rec);
struct tevent_req *dbwrap_watched_watch_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct db_record *rec,
+ uint64_t resumed_instance,
struct server_id blocker)
{
struct db_context *db = dbwrap_record_get_db(rec);
return tevent_req_post(req, ev);
}
- if (wrec->added.instance == 0) {
+ if (resumed_instance == 0 && wrec->added.instance == 0) {
/*
* Adding a new instance
*/
instance = dbwrap_watched_watch_add_instance(rec);
+ } else if (resumed_instance != 0 && wrec->added.instance == 0) {
+ /*
+ * Resuming an existing instance that was
+ * already present before do_locked started
+ */
+ instance = resumed_instance;
+ } else if (resumed_instance == wrec->added.instance) {
+ /*
+ * The caller used dbwrap_watched_watch_add_instance()
+ * already during this do_locked() invocation.
+ */
+ instance = resumed_instance;
} else {
tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
return tevent_req_post(req, ev);
* dbwrap_watched_record_wakeup().
*/
talloc_set_destructor(state, NULL);
+ state->watcher.instance = 0;
tevent_req_done(req);
}
NTSTATUS dbwrap_watched_watch_recv(struct tevent_req *req,
+ uint64_t *pkeep_instance,
bool *blockerdead,
struct server_id *blocker)
{
tevent_req_received(req);
return status;
}
+ if (pkeep_instance != NULL) {
+ *pkeep_instance = state->watcher.instance;
+ /*
+ * No need to remove ourselves anymore,
+ * the caller will take care of removing itself.
+ */
+ talloc_set_destructor(state, NULL);
+ }
if (blockerdead != NULL) {
*blockerdead = state->blockerdead;
}
struct db_context *db_open_watched(TALLOC_CTX *mem_ctx,
struct db_context **backend,
struct messaging_context *msg);
+uint64_t dbwrap_watched_watch_add_instance(struct db_record *rec);
+void dbwrap_watched_watch_remove_instance(struct db_record *rec, uint64_t instance);
+void dbwrap_watched_watch_skip_alerting(struct db_record *rec);
struct tevent_req *dbwrap_watched_watch_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct db_record *rec,
+ uint64_t resume_instance,
struct server_id blocker);
NTSTATUS dbwrap_watched_watch_recv(struct tevent_req *req,
+ uint64_t *pkeep_instance,
bool *blockerdead,
struct server_id *blocker);
}
state->watch_req = dbwrap_watched_watch_send(
- state->req_state, state->req_state->ev, rec, blocker);
+ state->req_state, state->req_state->ev, rec, 0, blocker);
if (state->watch_req == NULL) {
state->status = NT_STATUS_NO_MEMORY;
}
bool blockerdead = false;
NTSTATUS status;
- status = dbwrap_watched_watch_recv(subreq, &blockerdead, &blocker);
+ status = dbwrap_watched_watch_recv(subreq, NULL, &blockerdead, &blocker);
DBG_DEBUG("watch_recv returned %s\n", nt_errstr(status));
TALLOC_FREE(subreq);
DBG_DEBUG("state->unique_data_epoch=%"PRIu64"\n", state->unique_data_epoch);
subreq = dbwrap_watched_watch_send(
- state, state->ev, rec, state->blocker);
+ state, state->ev, rec, 0, state->blocker);
if (subreq == NULL) {
state->status = NT_STATUS_NO_MEMORY;
return;
}
subreq = dbwrap_watched_watch_send(
- state, state->ev, rec, state->blocker);
+ state, state->ev, rec, 0, state->blocker);
if (subreq == NULL) {
state->status = NT_STATUS_NO_MEMORY;
return;
NTSTATUS status;
status = dbwrap_watched_watch_recv(
- subreq, &state->blockerdead, &state->blocker);
+ subreq, NULL, &state->blockerdead, &state->blocker);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
subreq = dbwrap_watched_watch_send(state,
state->ev,
state->db_rec,
+ 0, /* resume_instance */
global->server_id);
if (tevent_req_nomem(subreq, req)) {
return;
struct tevent_req);
NTSTATUS status;
- status = dbwrap_watched_watch_recv(subreq, NULL, NULL);
+ status = dbwrap_watched_watch_recv(subreq, NULL, NULL, NULL);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
subreq = dbwrap_watched_watch_send(state, state->ev, state->db_rec,
+ 0, /* resume_instance */
(struct server_id){0});
if (tevent_req_nomem(subreq, req)) {
TALLOC_FREE(state->db_rec);
uint32_t global_id;
NTSTATUS status;
- status = dbwrap_watched_watch_recv(subreq, NULL, NULL);
+ status = dbwrap_watched_watch_recv(subreq, NULL, NULL, NULL);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
goto fail;
}
req = dbwrap_watched_watch_send(talloc_tos(), ev, rec,
+ 0, /* resume_instance */
(struct server_id){0});
if (req == NULL) {
fprintf(stderr, "dbwrap_record_watch_send failed\n");
goto fail;
}
- status = dbwrap_watched_watch_recv(req, NULL, NULL);
+ status = dbwrap_watched_watch_recv(req, NULL, NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "dbwrap_record_watch_recv failed: %s\n",
nt_errstr(status));
}
req = dbwrap_watched_watch_send(
- db, ev, rec, (struct server_id) { 0 });
+ db, ev, rec, 0, (struct server_id) { 0 });
if (req == NULL) {
fprintf(stderr, "dbwrap_watched_watch_send failed\n");
exit(2);
bool ok;
state->req1 = dbwrap_watched_watch_send(
- state->mem_ctx, state->ev, rec, (struct server_id) { .pid=0 });
+ state->mem_ctx, state->ev, rec, 0, (struct server_id) { .pid=0 });
if (state->req1 == NULL) {
goto nomem;
}
}
state->req2 = dbwrap_watched_watch_send(
- state->mem_ctx, state->ev, rec, (struct server_id) { .pid=0 });
+ state->mem_ctx, state->ev, rec, 0, (struct server_id) { .pid=0 });
if (state->req2 == NULL) {
goto nomem;
}
static void dbwrap_watch4_done1(struct tevent_req *subreq)
{
struct dbwrap_watch4_state *state = tevent_req_callback_data_void(subreq);
- state->status1 = dbwrap_watched_watch_recv(subreq, NULL, NULL);
+ state->status1 = dbwrap_watched_watch_recv(subreq, NULL, NULL, NULL);
TALLOC_FREE(subreq);
printf("req1 finished: %s\n", nt_errstr(state->status1));
state->req1 = NULL;
static void dbwrap_watch4_done2(struct tevent_req *subreq)
{
struct dbwrap_watch4_state *state = tevent_req_callback_data_void(subreq);
- state->status2 = dbwrap_watched_watch_recv(subreq, NULL, NULL);
+ state->status2 = dbwrap_watched_watch_recv(subreq, NULL, NULL, NULL);
TALLOC_FREE(subreq);
printf("req2 finished: %s\n", nt_errstr(state->status2));
state->req2 = NULL;