Ignore:
Timestamp:
Nov 25, 2013, 6:40:10 PM (12 years ago)
Author:
Silvan Scherrer
Message:

Samba 3.5: use fcntl and friends for locking

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.5.x/lib/tdb/common/lock.c

    r829 r836  
    3030#define TDB_MARK_LOCK 0x80000000
    3131
    32 #ifdef __OS2__
    33 
    34 static char* lock_type( int lck)
    35 {
    36         static char buffer[16];
    37         switch(lck) {
    38         case F_GETLK: return "F_GETLK";
    39         case F_SETLK: return "F_SETLK";
    40         case F_SETLKW: return "F_SETLKW";
    41         default:
    42                 sprintf( buffer, "unknown %d", lck);
    43         }
    44         return buffer;
    45 }
    46 
    47 static char* read_type( int rw)
    48 {
    49         static char buffer[16];
    50         switch(rw) {
    51         case F_RDLCK: return "F_RDLCK";
    52         case F_UNLCK: return "F_UNLCK";
    53         case F_WRLCK: return "F_WRLCK";
    54         default:
    55                 sprintf( buffer, "unknown %d", rw);
    56         }
    57         return buffer;
    58 }
    59 
    60 static int _mutex_brlock(struct tdb_context *tdb, tdb_off_t offset,
    61                int rw_type, int lck_type, int probe, size_t len)
    62 {
    63         HMTX    hSem;
    64         ULONG   ulTimeout;
    65         APIRET  rc;
    66        
    67         switch( offset) {
    68         case GLOBAL_LOCK:
    69                 hSem = tdb->hGlobalLock;
    70                 break;
    71         case ACTIVE_LOCK:
    72                 hSem = tdb->hActiveLock;
    73                 break;
    74         case TRANSACTION_LOCK:
    75                 hSem = tdb->hTransactionLock;
    76                 break;
    77         default:
    78                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown offset %d\n", offset));
    79                 exit(1);
    80         }
    81         if (hSem == 0) {
    82                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown sem handle offset %d\n", offset));
    83                 exit(1);
    84         }
    85 
    86         TDB_LOG((tdb, TDB_DEBUG_TRACE,"_mutex_brlock handle %d, offset %d\n", hSem, offset));
    87 
    88         if (lck_type == F_SETLKW)
    89                 ulTimeout = SEM_INDEFINITE_WAIT;
    90         else
    91                 ulTimeout = SEM_IMMEDIATE_RETURN;
    92 
    93         switch (rw_type) {
    94         case F_UNLCK:
    95                 rc = DosReleaseMutexSem( hSem);
    96                 break;
    97         case F_RDLCK:
    98         case F_WRLCK:
    99                 rc = DosRequestMutexSem( hSem, ulTimeout);
    100                 break;
    101         default:
    102                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown rw_type request %d\n", rw_type));
    103                 exit(1);
    104                 break;
    105         }
    106 
    107         if (rc == NO_ERROR
    108                 || rc == ERROR_SEM_OWNER_DIED
    109                 || rc == ERROR_NOT_OWNER)
    110                 return 0;
    111 
    112         errno = EINVAL;
    113         TDB_LOG(( tdb, TDB_DEBUG_ERROR, "_mutex_brlock pid %X, failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d, rc=%d\n",
    114                  getpid(), tdb->fd, offset, rw_type, lck_type, (int)len, rc));
    115         tdb->ecode = TDB_ERR_LOCK;
    116         return -1;
    117 }
    118 #endif
    11932
    12033void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
     
    13548{
    13649
    137 #ifdef __OS2__
    138         APIRET      rc;
    139         ULONG       fAccess = 0;
    140         FILELOCK    lockArea = {0}, unlockArea = {0};
    141 
    142         TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_brlock in pid %X, fd %d, lck_type %s, rw_type %s, offset %d, len %d\n",
    143                 getpid(), tdb->fd, lock_type(lck_type), read_type(rw_type), offset, len));
    144 
    145         if (tdb->flags & TDB_NOLOCK) {
    146                 return 0;
    147         }
    148 
    149         if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) {
    150                 tdb->ecode = TDB_ERR_RDONLY;
    151                 return -1;
    152         }
    153        
    154         switch( offset) {
    155         case GLOBAL_LOCK:
    156         case ACTIVE_LOCK:
    157         case TRANSACTION_LOCK:
    158                 return _mutex_brlock( tdb, offset, rw_type,  lck_type,  probe, len);
    159         }
    160 
    161         /* flags and order */
    162         switch (rw_type)
    163         {
    164                 case F_UNLCK:
    165                         unlockArea.lOffset = offset;
    166                         unlockArea.lRange  = len ? len : LONG_MAX;
    167                         break;
    168                 case F_RDLCK:
    169                         lockArea.lOffset = offset;
    170                         lockArea.lRange  = len ? len : LONG_MAX;
    171                         fAccess = 1; /* read-only */
    172                 case F_WRLCK:
    173                         lockArea.lOffset = offset;
    174                         lockArea.lRange  = len ? len : LONG_MAX;
    175                         break;
    176                 default:
    177                         break;
    178         }
    179                
    180         rc = DosSetFileLocks(tdb->fd, &unlockArea, &lockArea, SEM_IMMEDIATE_RETURN, fAccess);
    181 
    182         if (rc != NO_ERROR && lck_type == F_SETLKW) {
    183                 int     count = 20;
    184                 do {
    185                         rc = DosSetFileLocks(tdb->fd, &unlockArea, &lockArea, 100, fAccess);
    186                         count--;
    187                 } while( count>0 && rc !=NO_ERROR);
    188 
    189         }
    190 
    191         TDB_LOG(( tdb, TDB_DEBUG_TRACE, "tdb_brlock out pid %d, fd %d, lck_type %s, rw_type %s, offset %d, len %d, rc=%d\n",
    192                 getpid(), tdb->fd, lock_type(lck_type), read_type(rw_type), offset, len, rc));
    193 
    194         if (rc != NO_ERROR) {
    195                 errno  = EINVAL;
    196                 /* Generic lock error. errno set by fcntl.
    197                  * EAGAIN is an expected return from non-blocking
    198                  * locks. */
    199                 if (!probe && lck_type != F_SETLK) {
    200                         /* Ensure error code is set for log fun to examine. */
    201                         tdb->ecode = TDB_ERR_LOCK;
    202                         TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n",
    203                                  tdb->fd, offset, rw_type, lck_type, (int)len));
    204                 }
    205 
    206                 TDB_LOG(( tdb, TDB_DEBUG_TRACE, "tdb_brlock pid %X, failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n",
    207                          getpid(), tdb->fd, offset, rw_type, lck_type, (int)len));
    208                 tdb->ecode = TDB_ERR_LOCK;
    209                 return -1;
    210         }
    211 #else
    212 
    21350        struct flock fl;
    21451        int ret;
     
    22663        fl.l_whence = SEEK_SET;
    22764        fl.l_start = offset;
     65#ifdef __OS2__
     66        fl.l_len = len ? len:LONG_MAX;
     67#else
    22868        fl.l_len = len;
     69#endif
    22970        fl.l_pid = 0;
    23071
     
    25192                return -1;
    25293        }
    253 #endif
    25494        return 0;
    25595
     
    268108        while (count--) {
    269109                struct timeval tv;
    270 
    271 #ifdef __OS2__
    272                 // YD we cannot upgrade without an unlock first...
    273                 tdb_brlock(tdb, offset, F_UNLCK, F_SETLKW, 1, len);
    274 #endif
    275110
    276111                if (tdb_brlock(tdb, offset, F_WRLCK, F_SETLKW, 1, len) == 0) {
Note: See TracChangeset for help on using the changeset viewer.