mirror of
https://github.com/samba-team/samba.git
synced 2025-03-22 02:50:28 +03:00
Split ctdb_release_lock() into a function to release the locvk and another function to free the data structures.
This allows us to keep the datastructure valid after the lock has been released by the application and we can trap and warn when the application is accessing the lock after it has been released. I.e. application bugs. (This used to be ctdb commit 463a266205f145cd9c4c36b9c59d3747eeef0e2e)
This commit is contained in:
parent
6e0d612750
commit
b9e5c8a47b
@ -214,6 +214,9 @@ struct ctdb_db *ctdb_attachdb_recv(struct ctdb_connection *ctdb,
|
||||
*
|
||||
* You MUST NOT block during holding this lock and MUST release it
|
||||
* quickly by performing ctdb_release_lock(lock).
|
||||
* Do NOT make any system calls that may block while holding the lock.
|
||||
*
|
||||
* Try to release the lock as quickly as possible.
|
||||
*/
|
||||
struct ctdb_lock;
|
||||
|
||||
|
@ -642,10 +642,26 @@ void ctdb_release_lock(struct ctdb_lock *lock)
|
||||
lock->held = false;
|
||||
remove_lock(lock->ctdb_db->ctdb, lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void ctdb_free_lock(struct ctdb_lock *lock)
|
||||
{
|
||||
if (lock->held) {
|
||||
errno = EEXIST;
|
||||
DEBUG(lock->ctdb_db->ctdb, LOG_ERR,
|
||||
"Lock freed before it was released");
|
||||
ctdb_release_lock(lock);
|
||||
}
|
||||
free(lock->hdr);
|
||||
free(lock);
|
||||
}
|
||||
|
||||
static void ctdb_destroy_lock(struct ctdb_lock *lock)
|
||||
{
|
||||
ctdb_release_lock(lock);
|
||||
ctdb_free_lock(lock);
|
||||
}
|
||||
|
||||
/* We keep the lock if local node is the dmaster. */
|
||||
static bool try_readrecordlock(struct ctdb_lock *lock, TDB_DATA *data)
|
||||
{
|
||||
@ -676,7 +692,7 @@ static bool try_readrecordlock(struct ctdb_lock *lock, TDB_DATA *data)
|
||||
static void destroy_lock(struct ctdb_connection *ctdb,
|
||||
struct ctdb_request *req)
|
||||
{
|
||||
ctdb_release_lock(req->extra);
|
||||
ctdb_destroy_lock(req->extra);
|
||||
}
|
||||
|
||||
static void readrecordlock_retry(struct ctdb_connection *ctdb,
|
||||
@ -704,6 +720,7 @@ static void readrecordlock_retry(struct ctdb_connection *ctdb,
|
||||
/* Now it's their responsibility to free lock & request! */
|
||||
req->extra_destructor = NULL;
|
||||
lock->callback(lock->ctdb_db, lock, data, private);
|
||||
ctdb_free_lock(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -743,6 +760,7 @@ ctdb_readrecordlock_async(struct ctdb_db *ctdb_db, TDB_DATA key,
|
||||
/* Fast path. */
|
||||
if (try_readrecordlock(lock, &data)) {
|
||||
callback(ctdb_db, lock, data, cbdata);
|
||||
ctdb_free_lock(lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -752,7 +770,7 @@ ctdb_readrecordlock_async(struct ctdb_db *ctdb_db, TDB_DATA key,
|
||||
if (!req) {
|
||||
DEBUG(ctdb_db->ctdb, LOG_ERR,
|
||||
"ctdb_readrecordlock_async: allocation failed");
|
||||
ctdb_release_lock(lock);
|
||||
ctdb_destroy_lock(lock);
|
||||
return NULL;
|
||||
}
|
||||
req->extra = lock;
|
||||
|
@ -109,9 +109,11 @@ static void rrl_cb(struct ctdb_db *ctdb_db,
|
||||
data.dsize = strlen(tmp) + 1;
|
||||
ctdb_writerecord(lock, data);
|
||||
|
||||
/* Release the lock as quickly as possible */
|
||||
ctdb_release_lock(lock);
|
||||
|
||||
printf("Wrote new record : %s\n", tmp);
|
||||
|
||||
ctdb_release_lock(lock);
|
||||
}
|
||||
|
||||
static bool registered = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user