/ Check-in [13ed106c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added fix to os_win.c for race conditions from os_unix.c; added saving of errno in two places.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 13ed106c8c279422a6159e28c6887d13a88b7b8b
User & Date: shaneh 2010-07-20 20:23:38
Original Comment: Added fix for race conditions from os_unix.c; added saving of errno in two places.
Context
2010-07-21
16:16
Version 3.7.0 check-in: b36b105e user: drh tags: trunk, release
2010-07-20
20:23
Added fix to os_win.c for race conditions from os_unix.c; added saving of errno in two places. check-in: 13ed106c user: shaneh tags: trunk
18:59
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. check-in: 3b7330c1 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_win.c.

  1189   1189   **
  1190   1190   ** Function winShmMutexHeld() is used to assert() that the global mutex 
  1191   1191   ** is held when required. This function is only used as part of assert() 
  1192   1192   ** statements. e.g.
  1193   1193   **
  1194   1194   **   winShmEnterMutex()
  1195   1195   **     assert( winShmMutexHeld() );
  1196         -**   winEnterLeave()
         1196  +**   winShmLeaveMutex()
  1197   1197   */
  1198   1198   static void winShmEnterMutex(void){
  1199   1199     sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  1200   1200   }
  1201   1201   static void winShmLeaveMutex(void){
  1202   1202     sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  1203   1203   }
................................................................................
  1316   1316   
  1317   1317     /* Release/Acquire the system-level lock */
  1318   1318     if( lockType==_SHM_UNLCK ){
  1319   1319       rc = UnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp);
  1320   1320     }else{
  1321   1321       rc = LockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp);
  1322   1322     }
  1323         -  rc = (rc!=0) ? SQLITE_OK : SQLITE_BUSY;
         1323  +  
         1324  +  if( rc!= 0 ){
         1325  +    rc = SQLITE_OK;
         1326  +  }else{
         1327  +    pFile->lastErrno =  GetLastError();
         1328  +    rc = SQLITE_BUSY;
         1329  +  }
  1324   1330   
  1325   1331     OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", 
  1326   1332              pFile->hFile.h,
  1327   1333              rc==SQLITE_OK ? "ok" : "failed",
  1328   1334              lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx",
  1329         -           GetLastError()));
         1335  +           pFile->lastErrno));
  1330   1336   
  1331   1337     return rc;
  1332   1338   }
  1333   1339   
  1334   1340   /* Forward references to VFS methods */
  1335   1341   static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
  1336   1342   static int winDelete(sqlite3_vfs *,const char*,int);
................................................................................
  1453   1459         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
  1454   1460       }
  1455   1461       if( rc ) goto shm_open_err;
  1456   1462     }
  1457   1463   
  1458   1464     /* Make the new connection a child of the winShmNode */
  1459   1465     p->pShmNode = pShmNode;
  1460         -  p->pNext = pShmNode->pFirst;
  1461   1466   #ifdef SQLITE_DEBUG
  1462   1467     p->id = pShmNode->nextShmId++;
  1463   1468   #endif
  1464         -  pShmNode->pFirst = p;
  1465   1469     pShmNode->nRef++;
  1466   1470     pDbFd->pShm = p;
  1467   1471     winShmLeaveMutex();
         1472  +
         1473  +  /* The reference count on pShmNode has already been incremented under
         1474  +  ** the cover of the winShmEnterMutex() mutex and the pointer from the
         1475  +  ** new (struct winShm) object to the pShmNode has been set. All that is
         1476  +  ** left to do is to link the new object into the linked list starting
         1477  +  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 
         1478  +  ** mutex.
         1479  +  */
         1480  +  sqlite3_mutex_enter(pShmNode->mutex);
         1481  +  p->pNext = pShmNode->pFirst;
         1482  +  pShmNode->pFirst = p;
         1483  +  sqlite3_mutex_leave(pShmNode->mutex);
  1468   1484     return SQLITE_OK;
  1469   1485   
  1470   1486     /* Jump here on any error */
  1471   1487   shm_open_err:
  1472   1488     winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
  1473   1489     winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
  1474   1490     sqlite3_free(p);
................................................................................
  2068   2084       );
  2069   2085   #endif
  2070   2086     }
  2071   2087     OSTRACE(("OPEN %d %s 0x%lx %s\n", 
  2072   2088              h, zName, dwDesiredAccess, 
  2073   2089              h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
  2074   2090     if( h==INVALID_HANDLE_VALUE ){
         2091  +    pFile->lastErrno = GetLastError();
  2075   2092       free(zConverted);
  2076   2093       if( flags & SQLITE_OPEN_READWRITE ){
  2077   2094         return winOpen(pVfs, zName, id, 
  2078   2095                ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
  2079   2096       }else{
  2080   2097         return SQLITE_CANTOPEN_BKPT;
  2081   2098       }