--- parser3/src/main/pa_os.C 2015/10/26 01:21:59 1.15 +++ parser3/src/main/pa_os.C 2024/11/04 17:47:46 1.25 @@ -1,18 +1,62 @@ /** @file Parser: commonly functions. - Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com) - Author: Alexandr Petrosian (http://paf.design.ru) + Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #include "pa_config_includes.h" #include "pa_os.h" -volatile const char * IDENT_PA_OS_C="$Id: pa_os.C,v 1.15 2015/10/26 01:21:59 moko Exp $" IDENT_PA_OS_H; +volatile const char * IDENT_PA_OS_C="$Id: pa_os.C,v 1.25 2024/11/04 17:47:46 moko Exp $" IDENT_PA_OS_H; + +unsigned int pa_lock_attempts=PA_LOCK_ATTEMPTS; #ifdef _MSC_VER #include -#endif + +#define PA_SH_LOCK 2 +#define PA_EX_LOCK 1 +#define PA_ULOCK 0 +#define FLOCK(operation) int status=pa_flock(fd, operation); +#define ERRNO pa_errno() + +int pa_flock(int fd, int operation) { + HANDLE hFile = (HANDLE)_get_osfhandle(fd); + if (hFile == INVALID_HANDLE_VALUE) { + return -1; + } + + OVERLAPPED overlapped = {0}; + + if (operation == PA_ULOCK) { + return UnlockFileEx(hFile, 0, MAXDWORD, MAXDWORD, &overlapped) ? 0 : -1; + } else { + DWORD flags = LOCKFILE_FAIL_IMMEDIATELY; + if (operation == PA_EX_LOCK) { + flags |= LOCKFILE_EXCLUSIVE_LOCK; + } + return LockFileEx(hFile, flags, 0, MAXDWORD, MAXDWORD, &overlapped) ? 0 : -1; + } +} + +int pa_errno() { + switch(GetLastError()) { + case ERROR_LOCK_VIOLATION: // real case: returning the same error as with _locking + return EACCES; + case ERROR_IO_PENDING: + return EAGAIN; + case ERROR_INVALID_HANDLE: + return EBADF; + case ERROR_NOT_LOCKED: + return ENOLCK; + } + return EACCES; +} + +#else + +#define ERRNO errno #ifdef HAVE_FLOCK @@ -22,14 +66,6 @@ volatile const char * IDENT_PA_OS_C="$Id #define FLOCK(operation) int status=flock(fd, operation); #else -#ifdef HAVE__LOCKING - -#define PA_SH_LOCK _LK_NBLCK -#define PA_EX_LOCK _LK_NBLCK -#define PA_ULOCK _LK_UNLCK -#define FLOCK(operation) lseek(fd, 0, SEEK_SET); int status=_locking(fd, operation, 1); - -#else #ifdef HAVE_FCNTL #define PA_SH_LOCK F_RDLCK @@ -52,25 +88,26 @@ volatile const char * IDENT_PA_OS_C="$Id #endif #endif #endif + #endif int pa_lock(int fd, int attempts, int operation){ while(true){ FLOCK(operation); - attempts--; - if(status==0 || attempts<=0){ - return status; - } + if(status==0) + return 0; + if(--attempts<=0) + return ERRNO; pa_sleep(PA_LOCK_WAIT_TIMEOUT_SECS, PA_LOCK_WAIT_TIMEOUT_USECS); } }; int pa_lock_shared_blocking(int fd) { - return pa_lock(fd, PA_LOCK_ATTEMPTS, PA_SH_LOCK); + return pa_lock(fd, pa_lock_attempts, PA_SH_LOCK); } int pa_lock_exclusive_blocking(int fd) { - return pa_lock(fd, PA_LOCK_ATTEMPTS, PA_EX_LOCK); + return pa_lock(fd, pa_lock_attempts, PA_EX_LOCK); } int pa_lock_exclusive_nonblocking(int fd) {