Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf8d7f29

Browse files
committed
Allow lwlocks to be disowned
To implement AIO writes, the backend initiating writes needs to transfer thelock ownership to the AIO subsystem, so the lock held during the write can bereleased in another backend.Other backends need to be able to "complete" an asynchronously started IO toavoid deadlocks (consider e.g. one backend starting IO for a buffer and thenwaiting for a heavyweight lock held by another relation followed by thecurrent holder of the heavyweight lock waiting for the IO to complete).To that end, this commit adds LWLockDisown() and LWLockReleaseDisowned(). Ifcode uses LWLockDisown() it's the code's responsibility to ensure that thelock is released in case of errors.Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>Discussion:https://postgr.es/m/1f6b50a7-38ef-4d87-8246-786d39f46ab9@iki.fi
1 parent44cbba9 commitf8d7f29

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

‎src/backend/storage/lmgr/lwlock.c

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,14 +1775,25 @@ LWLockUpdateVar(LWLock *lock, pg_atomic_uint64 *valptr, uint64 val)
17751775

17761776

17771777
/*
1778-
* LWLockRelease - release a previously acquired lock
1778+
* Stop treating lock as held by current backend.
1779+
*
1780+
* This is the code that can be shared between actually releasing a lock
1781+
* (LWLockRelease()) and just not tracking ownership of the lock anymore
1782+
* without releasing the lock (LWLockDisown()).
1783+
*
1784+
* Returns the mode in which the lock was held by the current backend.
1785+
*
1786+
* NB: This does not call RESUME_INTERRUPTS(), but leaves that responsibility
1787+
* of the caller.
1788+
*
1789+
* NB: This will leave lock->owner pointing to the current backend (if
1790+
* LOCK_DEBUG is set). This is somewhat intentional, as it makes it easier to
1791+
* debug cases of missing wakeups during lock release.
17791792
*/
1780-
void
1781-
LWLockRelease(LWLock*lock)
1793+
staticinlineLWLockMode
1794+
LWLockDisownInternal(LWLock*lock)
17821795
{
17831796
LWLockModemode;
1784-
uint32oldstate;
1785-
boolcheck_waiters;
17861797
inti;
17871798

17881799
/*
@@ -1802,7 +1813,18 @@ LWLockRelease(LWLock *lock)
18021813
for (;i<num_held_lwlocks;i++)
18031814
held_lwlocks[i]=held_lwlocks[i+1];
18041815

1805-
PRINT_LWDEBUG("LWLockRelease",lock,mode);
1816+
returnmode;
1817+
}
1818+
1819+
/*
1820+
* Helper function to release lock, shared between LWLockRelease() and
1821+
* LWLockeleaseDisowned().
1822+
*/
1823+
staticvoid
1824+
LWLockReleaseInternal(LWLock*lock,LWLockModemode)
1825+
{
1826+
uint32oldstate;
1827+
boolcheck_waiters;
18061828

18071829
/*
18081830
* Release my hold on lock, after that it can immediately be acquired by
@@ -1840,13 +1862,54 @@ LWLockRelease(LWLock *lock)
18401862
LOG_LWDEBUG("LWLockRelease",lock,"releasing waiters");
18411863
LWLockWakeup(lock);
18421864
}
1865+
}
1866+
1867+
1868+
/*
1869+
* Stop treating lock as held by current backend.
1870+
*
1871+
* After calling this function it's the callers responsibility to ensure that
1872+
* the lock gets released (via LWLockReleaseDisowned()), even in case of an
1873+
* error. This only is desirable if the lock is going to be released in a
1874+
* different process than the process that acquired it.
1875+
*/
1876+
void
1877+
LWLockDisown(LWLock*lock)
1878+
{
1879+
LWLockDisownInternal(lock);
1880+
1881+
RESUME_INTERRUPTS();
1882+
}
1883+
1884+
/*
1885+
* LWLockRelease - release a previously acquired lock
1886+
*/
1887+
void
1888+
LWLockRelease(LWLock*lock)
1889+
{
1890+
LWLockModemode;
1891+
1892+
mode=LWLockDisownInternal(lock);
1893+
1894+
PRINT_LWDEBUG("LWLockRelease",lock,mode);
1895+
1896+
LWLockReleaseInternal(lock,mode);
18431897

18441898
/*
18451899
* Now okay to allow cancel/die interrupts.
18461900
*/
18471901
RESUME_INTERRUPTS();
18481902
}
18491903

1904+
/*
1905+
* Release lock previously disowned with LWLockDisown().
1906+
*/
1907+
void
1908+
LWLockReleaseDisowned(LWLock*lock,LWLockModemode)
1909+
{
1910+
LWLockReleaseInternal(lock,mode);
1911+
}
1912+
18501913
/*
18511914
* LWLockReleaseClearVar - release a previously acquired lock, reset variable
18521915
*/

‎src/include/storage/lwlock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ extern bool LWLockAcquireOrWait(LWLock *lock, LWLockMode mode);
129129
externvoidLWLockRelease(LWLock*lock);
130130
externvoidLWLockReleaseClearVar(LWLock*lock,pg_atomic_uint64*valptr,uint64val);
131131
externvoidLWLockReleaseAll(void);
132+
externvoidLWLockDisown(LWLock*l);
133+
externvoidLWLockReleaseDisowned(LWLock*l,LWLockModemode);
132134
externboolLWLockHeldByMe(LWLock*lock);
133135
externboolLWLockAnyHeldByMe(LWLock*lock,intnlocks,size_tstride);
134136
externboolLWLockHeldByMeInMode(LWLock*lock,LWLockModemode);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp