/ Check-in [32ab3657]
Login

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

Overview
Comment:In winAccess, save the Win32 last error value prior to invoking user logging callback. Also, explicitly pass the Win32 last error value to winLogError in order to keep it accurate. Fixes a problem reported on the mailing list.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 32ab365715e2c50f30aa2f92a323857b9d917bf6
User & Date: mistachkin 2011-11-10 20:21:20
Context
2011-11-10
21:45
Expand passing of a last error argument to the getLastErrorMsg function. Also, remove unused SQLITE_W32_THREADS define. check-in: 8f287979 user: mistachkin tags: trunk
20:21
In winAccess, save the Win32 last error value prior to invoking user logging callback. Also, explicitly pass the Win32 last error value to winLogError in order to keep it accurate. Fixes a problem reported on the mailing list. check-in: 32ab3657 user: mistachkin tags: trunk
2011-11-09
18:07
Omit an unnecessary Sleep() call in windows pending-lock retry logic. Enhance the comment on that logic to discourage people from copying it into other VFSes. check-in: 0c951a97 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_win.c.

   626    626   ** FormatMessage.
   627    627   **
   628    628   ** The first argument passed to the macro should be the error code that
   629    629   ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). 
   630    630   ** The two subsequent arguments should be the name of the OS function that
   631    631   ** failed and the the associated file-system path, if any.
   632    632   */
   633         -#define winLogError(a,b,c)     winLogErrorAtLine(a,b,c,__LINE__)
          633  +#define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
   634    634   static int winLogErrorAtLine(
   635    635     int errcode,                    /* SQLite error code */
          636  +  DWORD lastErrno,                /* Win32 last error */
   636    637     const char *zFunc,              /* Name of OS function that failed */
   637    638     const char *zPath,              /* File path associated with error */
   638    639     int iLine                       /* Source line number where error occurred */
   639    640   ){
   640    641     char zMsg[500];                 /* Human readable error text */
   641    642     int i;                          /* Loop counter */
   642         -  DWORD iErrno = GetLastError();  /* Error code */
   643    643   
   644    644     zMsg[0] = 0;
   645    645     getLastErrorMsg(sizeof(zMsg), zMsg);
   646    646     assert( errcode!=SQLITE_OK );
   647    647     if( zPath==0 ) zPath = "";
   648    648     for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
   649    649     zMsg[i] = 0;
   650    650     sqlite3_log(errcode,
   651    651         "os_win.c:%d: (%d) %s(%s) - %s",
   652         -      iLine, iErrno, zFunc, zPath, zMsg
          652  +      iLine, lastErrno, zFunc, zPath, zMsg
   653    653     );
   654    654   
   655    655     return errcode;
   656    656   }
   657    657   
   658    658   /*
   659    659   ** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
................................................................................
   776    776       if (*zTok == '\\') *zTok = '_';
   777    777     }
   778    778   
   779    779     /* Create/open the named mutex */
   780    780     pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
   781    781     if (!pFile->hMutex){
   782    782       pFile->lastErrno = GetLastError();
   783         -    winLogError(SQLITE_ERROR, "winceCreateLock1", zFilename);
          783  +    winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename);
   784    784       free(zName);
   785    785       return FALSE;
   786    786     }
   787    787   
   788    788     /* Acquire the mutex before continuing */
   789    789     winceMutexAcquire(pFile->hMutex);
   790    790     
................................................................................
   808    808     /* If we succeeded in making the shared memory handle, map it. */
   809    809     if (pFile->hShared){
   810    810       pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 
   811    811                FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
   812    812       /* If mapping failed, close the shared memory handle and erase it */
   813    813       if (!pFile->shared){
   814    814         pFile->lastErrno = GetLastError();
   815         -      winLogError(SQLITE_ERROR, "winceCreateLock2", zFilename);
          815  +      winLogError(SQLITE_ERROR, pFile->lastErrno,
          816  +               "winceCreateLock2", zFilename);
   816    817         CloseHandle(pFile->hShared);
   817    818         pFile->hShared = NULL;
   818    819       }
   819    820     }
   820    821   
   821    822     /* If shared memory could not be created, then close the mutex and fail */
   822    823     if (pFile->hShared == NULL){
................................................................................
  1054   1055     ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine 
  1055   1056     ** whether an error has actually occured, it is also necessary to call 
  1056   1057     ** GetLastError().
  1057   1058     */
  1058   1059     dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
  1059   1060     if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
  1060   1061       pFile->lastErrno = GetLastError();
  1061         -    winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile->zPath);
         1062  +    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
         1063  +             "seekWinFile", pFile->zPath);
  1062   1064       return 1;
  1063   1065     }
  1064   1066   
  1065   1067     return 0;
  1066   1068   }
  1067   1069   
  1068   1070   /*
................................................................................
  1101   1103       }
  1102   1104       free(pFile->zDeleteOnClose);
  1103   1105     }
  1104   1106   #endif
  1105   1107     OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
  1106   1108     OpenCounter(-1);
  1107   1109     return rc ? SQLITE_OK
  1108         -            : winLogError(SQLITE_IOERR_CLOSE, "winClose", pFile->zPath);
         1110  +            : winLogError(SQLITE_IOERR_CLOSE, GetLastError(),
         1111  +                          "winClose", pFile->zPath);
  1109   1112   }
  1110   1113   
  1111   1114   /*
  1112   1115   ** Read data from a file into a buffer.  Return SQLITE_OK if all
  1113   1116   ** bytes were read successfully and SQLITE_IOERR if anything goes
  1114   1117   ** wrong.
  1115   1118   */
................................................................................
  1129   1132   
  1130   1133     if( seekWinFile(pFile, offset) ){
  1131   1134       return SQLITE_FULL;
  1132   1135     }
  1133   1136     while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
  1134   1137       if( retryIoerr(&nRetry) ) continue;
  1135   1138       pFile->lastErrno = GetLastError();
  1136         -    return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath);
         1139  +    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
         1140  +             "winRead", pFile->zPath);
  1137   1141     }
  1138   1142     logIoerr(nRetry);
  1139   1143     if( nRead<(DWORD)amt ){
  1140   1144       /* Unread parts of the buffer must be zero-filled */
  1141   1145       memset(&((char*)pBuf)[nRead], 0, amt-nRead);
  1142   1146       return SQLITE_IOERR_SHORT_READ;
  1143   1147     }
................................................................................
  1188   1192     }
  1189   1193   
  1190   1194     if( rc ){
  1191   1195       if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
  1192   1196          || ( pFile->lastErrno==ERROR_DISK_FULL )){
  1193   1197         return SQLITE_FULL;
  1194   1198       }
  1195         -    return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath);
         1199  +    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
         1200  +             "winWrite", pFile->zPath);
  1196   1201     }else{
  1197   1202       logIoerr(nRetry);
  1198   1203     }
  1199   1204     return SQLITE_OK;
  1200   1205   }
  1201   1206   
  1202   1207   /*
................................................................................
  1218   1223     */
  1219   1224     if( pFile->szChunk>0 ){
  1220   1225       nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  1221   1226     }
  1222   1227   
  1223   1228     /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
  1224   1229     if( seekWinFile(pFile, nByte) ){
  1225         -    rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath);
         1230  +    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
         1231  +             "winTruncate1", pFile->zPath);
  1226   1232     }else if( 0==SetEndOfFile(pFile->h) ){
  1227   1233       pFile->lastErrno = GetLastError();
  1228         -    rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate2", pFile->zPath);
         1234  +    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
         1235  +             "winTruncate2", pFile->zPath);
  1229   1236     }
  1230   1237   
  1231   1238     OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
  1232   1239     return rc;
  1233   1240   }
  1234   1241   
  1235   1242   #ifdef SQLITE_TEST
................................................................................
  1292   1299   #else
  1293   1300     rc = FlushFileBuffers(pFile->h);
  1294   1301     SimulateIOError( rc=FALSE );
  1295   1302     if( rc ){
  1296   1303       return SQLITE_OK;
  1297   1304     }else{
  1298   1305       pFile->lastErrno = GetLastError();
  1299         -    return winLogError(SQLITE_IOERR_FSYNC, "winSync", pFile->zPath);
         1306  +    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
         1307  +             "winSync", pFile->zPath);
  1300   1308     }
  1301   1309   #endif
  1302   1310   }
  1303   1311   
  1304   1312   /*
  1305   1313   ** Determine the current size of a file in bytes
  1306   1314   */
................................................................................
  1313   1321     assert( id!=0 );
  1314   1322     SimulateIOError(return SQLITE_IOERR_FSTAT);
  1315   1323     lowerBits = GetFileSize(pFile->h, &upperBits);
  1316   1324     if(   (lowerBits == INVALID_FILE_SIZE)
  1317   1325        && ((error = GetLastError()) != NO_ERROR) )
  1318   1326     {
  1319   1327       pFile->lastErrno = error;
  1320         -    return winLogError(SQLITE_IOERR_FSTAT, "winFileSize", pFile->zPath);
         1328  +    return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
         1329  +             "winFileSize", pFile->zPath);
  1321   1330     }
  1322   1331     *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
  1323   1332     return SQLITE_OK;
  1324   1333   }
  1325   1334   
  1326   1335   /*
  1327   1336   ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
................................................................................
  1373   1382   #if SQLITE_OS_WINCE==0
  1374   1383     }else{
  1375   1384       res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
  1376   1385   #endif
  1377   1386     }
  1378   1387     if( res==0 && GetLastError()!=ERROR_NOT_LOCKED ){
  1379   1388       pFile->lastErrno = GetLastError();
  1380         -    winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath);
         1389  +    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
         1390  +             "unlockReadLock", pFile->zPath);
  1381   1391     }
  1382   1392     return res;
  1383   1393   }
  1384   1394   
  1385   1395   /*
  1386   1396   ** Lock the file with the lock specified by parameter locktype - one
  1387   1397   ** of the following:
................................................................................
  1576   1586             pFile->locktype, pFile->sharedLockByte));
  1577   1587     type = pFile->locktype;
  1578   1588     if( type>=EXCLUSIVE_LOCK ){
  1579   1589       UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  1580   1590       if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
  1581   1591         /* This should never happen.  We should always be able to
  1582   1592         ** reacquire the read lock */
  1583         -      rc = winLogError(SQLITE_IOERR_UNLOCK, "winUnlock", pFile->zPath);
         1593  +      rc = winLogError(SQLITE_IOERR_UNLOCK, GetLastError(),
         1594  +               "winUnlock", pFile->zPath);
  1584   1595       }
  1585   1596     }
  1586   1597     if( type>=RESERVED_LOCK ){
  1587   1598       UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
  1588   1599     }
  1589   1600     if( locktype==NO_LOCK && type>=SHARED_LOCK ){
  1590   1601       unlockReadLock(pFile);
................................................................................
  1967   1978   
  1968   1979       /* Check to see if another process is holding the dead-man switch.
  1969   1980       ** If not, truncate the file to zero length. 
  1970   1981       */
  1971   1982       if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
  1972   1983         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
  1973   1984         if( rc!=SQLITE_OK ){
  1974         -        rc = winLogError(SQLITE_IOERR_SHMOPEN, "winOpenShm", pDbFd->zPath);
         1985  +        rc = winLogError(SQLITE_IOERR_SHMOPEN, GetLastError(),
         1986  +                 "winOpenShm", pDbFd->zPath);
  1975   1987         }
  1976   1988       }
  1977   1989       if( rc==SQLITE_OK ){
  1978   1990         winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
  1979   1991         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
  1980   1992       }
  1981   1993       if( rc ) goto shm_open_err;
................................................................................
  2226   2238   
  2227   2239       /* The requested region is not mapped into this processes address space.
  2228   2240       ** Check to see if it has been allocated (i.e. if the wal-index file is
  2229   2241       ** large enough to contain the requested region).
  2230   2242       */
  2231   2243       rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
  2232   2244       if( rc!=SQLITE_OK ){
  2233         -      rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap1", pDbFd->zPath);
         2245  +      rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(),
         2246  +               "winShmMap1", pDbFd->zPath);
  2234   2247         goto shmpage_out;
  2235   2248       }
  2236   2249   
  2237   2250       if( sz<nByte ){
  2238   2251         /* The requested memory region does not exist. If isWrite is set to
  2239   2252         ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
  2240   2253         **
  2241   2254         ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
  2242   2255         ** the requested memory region.
  2243   2256         */
  2244   2257         if( !isWrite ) goto shmpage_out;
  2245   2258         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
  2246   2259         if( rc!=SQLITE_OK ){
  2247         -        rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap2", pDbFd->zPath);
         2260  +        rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(),
         2261  +                 "winShmMap2", pDbFd->zPath);
  2248   2262           goto shmpage_out;
  2249   2263         }
  2250   2264       }
  2251   2265   
  2252   2266       /* Map the requested memory region into this processes address space. */
  2253   2267       apNew = (struct ShmRegion *)sqlite3_realloc(
  2254   2268           pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
................................................................................
  2277   2291           );
  2278   2292           OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
  2279   2293                    (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion,
  2280   2294                    pMap ? "ok" : "failed"));
  2281   2295         }
  2282   2296         if( !pMap ){
  2283   2297           pShmNode->lastErrno = GetLastError();
  2284         -        rc = winLogError(SQLITE_IOERR_SHMMAP, "winShmMap3", pDbFd->zPath);
         2298  +        rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
         2299  +                 "winShmMap3", pDbFd->zPath);
  2285   2300           if( hMap ) CloseHandle(hMap);
  2286   2301           goto shmpage_out;
  2287   2302         }
  2288   2303   
  2289   2304         pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
  2290   2305         pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
  2291   2306         pShmNode->nRegion++;
................................................................................
  2611   2626   
  2612   2627     OSTRACE(("OPEN %d %s 0x%lx %s\n", 
  2613   2628              h, zName, dwDesiredAccess, 
  2614   2629              h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
  2615   2630   
  2616   2631     if( h==INVALID_HANDLE_VALUE ){
  2617   2632       pFile->lastErrno = GetLastError();
  2618         -    winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
         2633  +    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
  2619   2634       free(zConverted);
  2620   2635       if( isReadWrite && !isExclusive ){
  2621   2636         return winOpen(pVfs, zName, id, 
  2622   2637                ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
  2623   2638       }else{
  2624   2639         return SQLITE_CANTOPEN_BKPT;
  2625   2640       }
................................................................................
  2704   2719       rc = 1;
  2705   2720       while( GetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES &&
  2706   2721              (rc = DeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){}
  2707   2722       rc = rc ? SQLITE_OK : SQLITE_ERROR;
  2708   2723   #endif
  2709   2724     }
  2710   2725     if( rc ){
  2711         -    rc = winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename);
         2726  +    rc = winLogError(SQLITE_IOERR_DELETE, GetLastError(),
         2727  +             "winDelete", zFilename);
  2712   2728     }else{
  2713   2729       logIoerr(cnt);
  2714   2730     }
  2715   2731     free(zConverted);
  2716   2732     OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" )));
  2717   2733     return rc;
  2718   2734   }
................................................................................
  2751   2767             && sAttrData.nFileSizeHigh==0 
  2752   2768             && sAttrData.nFileSizeLow==0 ){
  2753   2769           attr = INVALID_FILE_ATTRIBUTES;
  2754   2770         }else{
  2755   2771           attr = sAttrData.dwFileAttributes;
  2756   2772         }
  2757   2773       }else{
         2774  +      DWORD lastErrno = GetLastError();
  2758   2775         logIoerr(cnt);
  2759         -      if( GetLastError()!=ERROR_FILE_NOT_FOUND ){
  2760         -        winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename);
         2776  +      if( lastErrno!=ERROR_FILE_NOT_FOUND ){
         2777  +        winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
  2761   2778           free(zConverted);
  2762   2779           return SQLITE_IOERR_ACCESS;
  2763   2780         }else{
  2764   2781           attr = INVALID_FILE_ATTRIBUTES;
  2765   2782         }
  2766   2783       }
  2767   2784   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.