diff options
author | dan <dan@noemail.net> | 2010-07-20 18:59:00 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2010-07-20 18:59:00 +0000 |
commit | 0668f5916e4032e5eeec8bf0a0d43d5a4428b921 (patch) | |
tree | 12d0979bb8a3e3d76106b4d9f5dc81b3280c0e52 /src/os_unix.c | |
parent | 74bec6b93f453065388a9a6c55dd745eeb2b340a (diff) | |
download | sqlite-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.c | 14 |
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 */ |