1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-01 05:47:28 +03:00
samba-mirror/source3/lib/dbwrap/dbwrap_watch.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

46 lines
1.7 KiB
C
Raw Normal View History

/*
Unix SMB/CIFS implementation.
Watch dbwrap record changes
Copyright (C) Volker Lendecke 2012
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __DBWRAP_WATCH_H__
#define __DBWRAP_WATCH_H__
#include <tevent.h>
#include "dbwrap/dbwrap.h"
#include "messages.h"
struct db_context *db_open_watched(TALLOC_CTX *mem_ctx,
struct db_context **backend,
struct messaging_context *msg);
s3:dbwrap_watch: allow callers of dbwrap_watched_watch_send/recv() to manage the watcher instances The destructor triggered by dbwrap_watched_watch_recv() will remove the watcher instance via a dedicated dbwrap_do_locked(), just calling dbwrap_watched_watch_remove_instance() inside. But the typical caller triggers a dbwrap_do_locked() again after dbwrap_watched_watch_recv() returned. Which means we call dbwrap_do_locked() twice. We now allow dbwrap_watched_watch_recv() to return the existing instance id (if it still exists) and removes the destructor. That way the caller can pass the given instance id to dbwrap_watched_watch_remove_instance() from within its own dbwrap_do_locked(), when it decides to leave the queue, because it's happy with the new state of the record. In order to get the best performance dbwrap_watched_watch_remove_instance() should be called before any dbwrap_record_storev() or dbwrap_record_delete(), because that will only trigger a single low level storev/delete. If the caller found out that the state of the record doesn't meet the expectations and the callers wants to continue watching the record (from its current position, most likely the first one), dbwrap_watched_watch_remove_instance() can be skipped and the instance id can be passed to dbwrap_watched_watch_send() again, in order to resume waiting on the existing instance. Currently the watcher instance were always removed (most likely from the first position) and re-added (to the last position), which may cause unfair latencies. In order to improve the overhead of adding a new watcher instance the caller can call dbwrap_watched_watch_add_instance() before any dbwrap_record_storev() or dbwrap_record_delete(), which will only result in a single low level storev/delete. The returned instance id is then passed to dbwrap_watched_watch_send(), within the same dbwrap_do_locked() run. It also adds a way to avoid alerting any callers during the current dbwrap_do_locked() run. Layers above may only want to wake up watchers during specific situations and while it's useless to wake others in other situations. This will soon be used to add more fairness to the g_lock code. Note that this commit only prepares the api for the above to be useful, the instance returned by dbwrap_watched_watch_recv() is most likely 0, which means the watcher entry was already removed, but that will change in the following commits. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15125 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
2022-06-30 15:53:47 +02:00
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);
void dbwrap_watched_watch_reset_alerting(struct db_record *rec);
void dbwrap_watched_watch_force_alerting(struct db_record *rec);
struct tevent_req *dbwrap_watched_watch_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct db_record *rec,
s3:dbwrap_watch: allow callers of dbwrap_watched_watch_send/recv() to manage the watcher instances The destructor triggered by dbwrap_watched_watch_recv() will remove the watcher instance via a dedicated dbwrap_do_locked(), just calling dbwrap_watched_watch_remove_instance() inside. But the typical caller triggers a dbwrap_do_locked() again after dbwrap_watched_watch_recv() returned. Which means we call dbwrap_do_locked() twice. We now allow dbwrap_watched_watch_recv() to return the existing instance id (if it still exists) and removes the destructor. That way the caller can pass the given instance id to dbwrap_watched_watch_remove_instance() from within its own dbwrap_do_locked(), when it decides to leave the queue, because it's happy with the new state of the record. In order to get the best performance dbwrap_watched_watch_remove_instance() should be called before any dbwrap_record_storev() or dbwrap_record_delete(), because that will only trigger a single low level storev/delete. If the caller found out that the state of the record doesn't meet the expectations and the callers wants to continue watching the record (from its current position, most likely the first one), dbwrap_watched_watch_remove_instance() can be skipped and the instance id can be passed to dbwrap_watched_watch_send() again, in order to resume waiting on the existing instance. Currently the watcher instance were always removed (most likely from the first position) and re-added (to the last position), which may cause unfair latencies. In order to improve the overhead of adding a new watcher instance the caller can call dbwrap_watched_watch_add_instance() before any dbwrap_record_storev() or dbwrap_record_delete(), which will only result in a single low level storev/delete. The returned instance id is then passed to dbwrap_watched_watch_send(), within the same dbwrap_do_locked() run. It also adds a way to avoid alerting any callers during the current dbwrap_do_locked() run. Layers above may only want to wake up watchers during specific situations and while it's useless to wake others in other situations. This will soon be used to add more fairness to the g_lock code. Note that this commit only prepares the api for the above to be useful, the instance returned by dbwrap_watched_watch_recv() is most likely 0, which means the watcher entry was already removed, but that will change in the following commits. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15125 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
2022-06-30 15:53:47 +02:00
uint64_t resume_instance,
struct server_id blocker);
NTSTATUS dbwrap_watched_watch_recv(struct tevent_req *req,
s3:dbwrap_watch: allow callers of dbwrap_watched_watch_send/recv() to manage the watcher instances The destructor triggered by dbwrap_watched_watch_recv() will remove the watcher instance via a dedicated dbwrap_do_locked(), just calling dbwrap_watched_watch_remove_instance() inside. But the typical caller triggers a dbwrap_do_locked() again after dbwrap_watched_watch_recv() returned. Which means we call dbwrap_do_locked() twice. We now allow dbwrap_watched_watch_recv() to return the existing instance id (if it still exists) and removes the destructor. That way the caller can pass the given instance id to dbwrap_watched_watch_remove_instance() from within its own dbwrap_do_locked(), when it decides to leave the queue, because it's happy with the new state of the record. In order to get the best performance dbwrap_watched_watch_remove_instance() should be called before any dbwrap_record_storev() or dbwrap_record_delete(), because that will only trigger a single low level storev/delete. If the caller found out that the state of the record doesn't meet the expectations and the callers wants to continue watching the record (from its current position, most likely the first one), dbwrap_watched_watch_remove_instance() can be skipped and the instance id can be passed to dbwrap_watched_watch_send() again, in order to resume waiting on the existing instance. Currently the watcher instance were always removed (most likely from the first position) and re-added (to the last position), which may cause unfair latencies. In order to improve the overhead of adding a new watcher instance the caller can call dbwrap_watched_watch_add_instance() before any dbwrap_record_storev() or dbwrap_record_delete(), which will only result in a single low level storev/delete. The returned instance id is then passed to dbwrap_watched_watch_send(), within the same dbwrap_do_locked() run. It also adds a way to avoid alerting any callers during the current dbwrap_do_locked() run. Layers above may only want to wake up watchers during specific situations and while it's useless to wake others in other situations. This will soon be used to add more fairness to the g_lock code. Note that this commit only prepares the api for the above to be useful, the instance returned by dbwrap_watched_watch_recv() is most likely 0, which means the watcher entry was already removed, but that will change in the following commits. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15125 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
2022-06-30 15:53:47 +02:00
uint64_t *pkeep_instance,
bool *blockerdead,
struct server_id *blocker);
#endif /* __DBWRAP_WATCH_H__ */