diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:28:19 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:28:19 +0000 |
commit | 18657a960e125336f704ea058e25c27bd3900dcb (patch) | |
tree | 17b438b680ed45a996d7b59951e6aa34023783f2 /www/c3ref/unlock_notify.html | |
parent | Initial commit. (diff) | |
download | sqlite3-upstream.tar.xz sqlite3-upstream.zip |
Adding upstream version 3.40.1.upstream/3.40.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'www/c3ref/unlock_notify.html')
-rw-r--r-- | www/c3ref/unlock_notify.html | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/www/c3ref/unlock_notify.html b/www/c3ref/unlock_notify.html new file mode 100644 index 0000000..c0d40d1 --- /dev/null +++ b/www/c3ref/unlock_notify.html @@ -0,0 +1,245 @@ +<!DOCTYPE html> +<html><head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<link href="../sqlite.css" rel="stylesheet"> +<title>Unlock Notification</title> +<!-- path=../ --> +</head> +<body> +<div class=nosearch> +<a href="../index.html"> +<img class="logo" src="../images/sqlite370_banner.gif" alt="SQLite" border="0"> +</a> +<div><!-- IE hack to prevent disappearing logo --></div> +<div class="tagline desktoponly"> +Small. Fast. Reliable.<br>Choose any three. +</div> +<div class="menu mainmenu"> +<ul> +<li><a href="../index.html">Home</a> +<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a> +<li class='wideonly'><a href='../about.html'>About</a> +<li class='desktoponly'><a href="../docs.html">Documentation</a> +<li class='desktoponly'><a href="../download.html">Download</a> +<li class='wideonly'><a href='../copyright.html'>License</a> +<li class='desktoponly'><a href="../support.html">Support</a> +<li class='desktoponly'><a href="../prosupport.html">Purchase</a> +<li class='search' id='search_menubutton'> +<a href="javascript:void(0)" onclick='toggle_search()'>Search</a> +</ul> +</div> +<div class="menu submenu" id="submenu"> +<ul> +<li><a href='../about.html'>About</a> +<li><a href='../docs.html'>Documentation</a> +<li><a href='../download.html'>Download</a> +<li><a href='../support.html'>Support</a> +<li><a href='../prosupport.html'>Purchase</a> +</ul> +</div> +<div class="searchmenu" id="searchmenu"> +<form method="GET" action="../search"> +<select name="s" id="searchtype"> +<option value="d">Search Documentation</option> +<option value="c">Search Changelog</option> +</select> +<input type="text" name="q" id="searchbox" value=""> +<input type="submit" value="Go"> +</form> +</div> +</div> +<script> +function toggle_div(nm) { +var w = document.getElementById(nm); +if( w.style.display=="block" ){ +w.style.display = "none"; +}else{ +w.style.display = "block"; +} +} +function toggle_search() { +var w = document.getElementById("searchmenu"); +if( w.style.display=="block" ){ +w.style.display = "none"; +} else { +w.style.display = "block"; +setTimeout(function(){ +document.getElementById("searchbox").focus() +}, 30); +} +} +function div_off(nm){document.getElementById(nm).style.display="none";} +window.onbeforeunload = function(e){div_off("submenu");} +/* Disable the Search feature if we are not operating from CGI, since */ +/* Search is accomplished using CGI and will not work without it. */ +if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){ +document.getElementById("search_menubutton").style.display = "none"; +} +/* Used by the Hide/Show button beside syntax diagrams, to toggle the */ +function hideorshow(btn,obj){ +var x = document.getElementById(obj); +var b = document.getElementById(btn); +if( x.style.display!='none' ){ +x.style.display = 'none'; +b.innerHTML='show'; +}else{ +x.style.display = ''; +b.innerHTML='hide'; +} +return false; +} +var antiRobot = 0; +function antiRobotGo(){ +if( antiRobot!=3 ) return; +antiRobot = 7; +var j = document.getElementById("mtimelink"); +if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); +} +function antiRobotDefense(){ +document.body.onmousedown=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousedown=null; +} +document.body.onmousemove=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousemove=null; +} +setTimeout(function(){ +antiRobot |= 1; +antiRobotGo(); +}, 100) +antiRobotGo(); +} +antiRobotDefense(); +</script> +<!-- keywords: sqlite3_unlock_notify --> +<div class=nosearch> +<a href="intro.html"><h2>SQLite C Interface</h2></a> +<h2>Unlock Notification</h2> +</div> +<blockquote><pre> +int sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); +</pre></blockquote> +<p> +When running in shared-cache mode, a database operation may fail with +an <a href="../rescode.html#locked">SQLITE_LOCKED</a> error if the required locks on the shared-cache or +individual tables within the shared-cache cannot be obtained. See +<a href="../sharedcache.html">SQLite Shared-Cache Mode</a> for a description of shared-cache locking. +This API may be used to register a callback that SQLite will invoke +when the connection currently holding the required lock relinquishes it. +This API is only available if the library was compiled with the +<a href="../compile.html#enable_unlock_notify">SQLITE_ENABLE_UNLOCK_NOTIFY</a> C-preprocessor symbol defined.</p> + +<p>See Also: <a href="../unlock_notify.html">Using the SQLite Unlock Notification Feature</a>.</p> + +<p>Shared-cache locks are released when a database connection concludes +its current transaction, either by committing it or rolling it back.</p> + +<p>When a connection (known as the blocked connection) fails to obtain a +shared-cache lock and SQLITE_LOCKED is returned to the caller, the +identity of the database connection (the blocking connection) that +has locked the required resource is stored internally. After an +application receives an SQLITE_LOCKED error, it may call the +sqlite3_unlock_notify() method with the blocked connection handle as +the first argument to register for a callback that will be invoked +when the blocking connections current transaction is concluded. The +callback is invoked from within the <a href="../c3ref/step.html">sqlite3_step</a> or <a href="../c3ref/close.html">sqlite3_close</a> +call that concludes the blocking connection's transaction.</p> + +<p>If sqlite3_unlock_notify() is called in a multi-threaded application, +there is a chance that the blocking connection will have already +concluded its transaction by the time sqlite3_unlock_notify() is invoked. +If this happens, then the specified callback is invoked immediately, +from within the call to sqlite3_unlock_notify().</p> + +<p>If the blocked connection is attempting to obtain a write-lock on a +shared-cache table, and more than one other connection currently holds +a read-lock on the same table, then SQLite arbitrarily selects one of +the other connections to use as the blocking connection.</p> + +<p>There may be at most one unlock-notify callback registered by a +blocked connection. If sqlite3_unlock_notify() is called when the +blocked connection already has a registered unlock-notify callback, +then the new callback replaces the old. If sqlite3_unlock_notify() is +called with a NULL pointer as its second argument, then any existing +unlock-notify callback is canceled. The blocked connections +unlock-notify callback may also be canceled by closing the blocked +connection using <a href="../c3ref/close.html">sqlite3_close()</a>.</p> + +<p>The unlock-notify callback is not reentrant. If an application invokes +any sqlite3_xxx API functions from within an unlock-notify callback, a +crash or deadlock may be the result.</p> + +<p>Unless deadlock is detected (see below), sqlite3_unlock_notify() always +returns SQLITE_OK.</p> + +<p><b>Callback Invocation Details</b></p> + +<p>When an unlock-notify callback is registered, the application provides a +single void* pointer that is passed to the callback when it is invoked. +However, the signature of the callback function allows SQLite to pass +it an array of void* context pointers. The first argument passed to +an unlock-notify callback is a pointer to an array of void* pointers, +and the second is the number of entries in the array.</p> + +<p>When a blocking connection's transaction is concluded, there may be +more than one blocked connection that has registered for an unlock-notify +callback. If two or more such blocked connections have specified the +same callback function, then instead of invoking the callback function +multiple times, it is invoked once with the set of void* context pointers +specified by the blocked connections bundled together into an array. +This gives the application an opportunity to prioritize any actions +related to the set of unblocked database connections.</p> + +<p><b>Deadlock Detection</b></p> + +<p>Assuming that after registering for an unlock-notify callback a +database waits for the callback to be issued before taking any further +action (a reasonable assumption), then using this API may cause the +application to deadlock. For example, if connection X is waiting for +connection Y's transaction to be concluded, and similarly connection +Y is waiting on connection X's transaction, then neither connection +will proceed and the system may remain deadlocked indefinitely.</p> + +<p>To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +detection. If a given call to sqlite3_unlock_notify() would put the +system in a deadlocked state, then SQLITE_LOCKED is returned and no +unlock-notify callback is registered. The system is said to be in +a deadlocked state if connection A has registered for an unlock-notify +callback on the conclusion of connection B's transaction, and connection +B has itself registered for an unlock-notify callback when connection +A's transaction is concluded. Indirect deadlock is also detected, so +the system is also considered to be deadlocked if connection B has +registered for an unlock-notify callback on the conclusion of connection +C's transaction, where connection C is waiting on connection A. Any +number of levels of indirection are allowed.</p> + +<p><b>The "DROP TABLE" Exception</b></p> + +<p>When a call to <a href="../c3ref/step.html">sqlite3_step()</a> returns SQLITE_LOCKED, it is almost +always appropriate to call sqlite3_unlock_notify(). There is however, +one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +SQLite checks if there are any currently executing SELECT statements +that belong to the same connection. If there are, SQLITE_LOCKED is +returned. In this case there is no "blocking connection", so invoking +sqlite3_unlock_notify() results in the unlock-notify callback being +invoked immediately. If the application then re-attempts the "DROP TABLE" +or "DROP INDEX" query, an infinite loop might be the result.</p> + +<p>One way around this problem is to check the extended error code returned +by an sqlite3_step() call. If there is a blocking connection, then the +extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +the special "DROP TABLE/INDEX" case, the extended error code is just +SQLITE_LOCKED. +</p><p>See also lists of + <a href="objlist.html">Objects</a>, + <a href="constlist.html">Constants</a>, and + <a href="funclist.html">Functions</a>.</p> + |