aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2010-07-20 18:59:00 +0000
committerdan <dan@noemail.net>2010-07-20 18:59:00 +0000
commit0668f5916e4032e5eeec8bf0a0d43d5a4428b921 (patch)
tree12d0979bb8a3e3d76106b4d9f5dc81b3280c0e52 /src/os_unix.c
parent74bec6b93f453065388a9a6c55dd745eeb2b340a (diff)
downloadsqlite-0668f5916e4032e5eeec8bf0a0d43d5a4428b921.tar.gz
sqlite-0668f5916e4032e5eeec8bf0a0d43d5a4428b921.zip
Fix a race condition in os_unix.c that may occur when one thread is opening a connection to a shared-memory block and another is either closing or locking the same shared-memory.
FossilOrigin-Name: 3b7330c19a5327322068e9460018fe0152b8ac87
Diffstat (limited to 'src/os_unix.c')
-rw-r--r--src/os_unix.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index 43487404b..9457516ca 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3387,14 +3387,24 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
/* Make the new connection a child of the unixShmNode */
p->pShmNode = pShmNode;
- p->pNext = pShmNode->pFirst;
#ifdef SQLITE_DEBUG
p->id = pShmNode->nextShmId++;
#endif
- pShmNode->pFirst = p;
pShmNode->nRef++;
pDbFd->pShm = p;
unixLeaveMutex();
+
+ /* The reference count on pShmNode has already been incremented under
+ ** the cover of the unixEnterMutex() mutex and the pointer from the
+ ** new (struct unixShm) object to the pShmNode has been set. All that is
+ ** left to do is to link the new object into the linked list starting
+ ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
+ ** mutex.
+ */
+ sqlite3_mutex_enter(pShmNode->mutex);
+ p->pNext = pShmNode->pFirst;
+ pShmNode->pFirst = p;
+ sqlite3_mutex_leave(pShmNode->mutex);
return SQLITE_OK;
/* Jump here on any error */