Ignore:
Timestamp:
Nov 25, 2013, 4:35:16 PM (12 years ago)
Author:
Silvan Scherrer
Message:

Samba 3.6: use fcntl and friends for locking

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/lib/tdb/common/lock.c

    r830 r834  
    2727
    2828#include "tdb_private.h"
    29 #ifdef __OS2__
    30 
    31 static char* lock_type( bool waitflag)
    32 {
    33         if (waitflag)
    34                 return "F_SETLKW";
    35         else
    36                 return "F_SETLK";
    37 }
    38 
    39 static char* read_type( int rw)
    40 {
    41         static char buffer[16];
    42         switch(rw) {
    43         case F_RDLCK: return "F_RDLCK";
    44         case F_UNLCK: return "F_UNLCK";
    45         case F_WRLCK: return "F_WRLCK";
    46         default:
    47                 sprintf( buffer, "unknown %d", rw);
    48         }
    49         return buffer;
    50 }
    51 
    52 static int _mutex_brlock(struct tdb_context *tdb, tdb_off_t offset,
    53                int rw_type, bool waitflag, size_t len)
    54 {
    55         HMTX    hSem;
    56         ULONG   ulTimeout;
    57         APIRET  rc;
    58        
    59         switch( offset) {
    60         case OPEN_LOCK:
    61                 hSem = tdb->hGlobalLock;
    62                 break;
    63         case ACTIVE_LOCK:
    64                 hSem = tdb->hActiveLock;
    65                 break;
    66         case TRANSACTION_LOCK:
    67                 hSem = tdb->hTransactionLock;
    68                 break;
    69         default:
    70                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown offset %d\n", offset));
    71                 exit(1);
    72                 break;
    73         }
    74 
    75         if (hSem == 0) {
    76                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown sem handle offset %d\n", offset));
    77                 exit(1);
    78         }
    79 
    80         TDB_LOG((tdb, TDB_DEBUG_TRACE,"_mutex_brlock handle %d, offset %d\n", hSem, offset));
    81 
    82         if (waitflag)
    83                 ulTimeout = SEM_INDEFINITE_WAIT;
    84         else
    85                 ulTimeout = SEM_IMMEDIATE_RETURN;
    86 
    87         switch (rw_type) {
    88         case F_UNLCK:
    89                 rc = DosReleaseMutexSem( hSem);
    90                 break;
    91         case F_RDLCK:
    92         case F_WRLCK:
    93                 rc = DosRequestMutexSem( hSem, ulTimeout);
    94                 break;
    95         default:
    96                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown rw_type request %d\n", rw_type));
    97                 exit(1);
    98                 break;
    99         }
    100 
    101         if (rc == NO_ERROR
    102                 || rc == ERROR_SEM_OWNER_DIED
    103                 || rc == ERROR_NOT_OWNER)
    104                 return 0;
    105 
    106         errno = EINVAL;
    107         TDB_LOG(( tdb, TDB_DEBUG_ERROR, "_mutex_brlock pid %d, failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d, rc=%d\n",
    108                  getpid(), tdb->fd, offset, rw_type, waitflag, (int)len, rc));
    109         tdb->ecode = TDB_ERR_LOCK;
    110         return -1;
    111 }
    112 #endif
    11329
    11430_PUBLIC_ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
     
    11834
    11935static int fcntl_lock(struct tdb_context *tdb,
    120                       int rw, tdb_off_t off, size_t len, bool waitflag)
    121 {
    122 #ifdef __OS2__
    123         APIRET      rc;
    124         ULONG       fAccess = 0; // default exclusiv
    125         FILELOCK    lockArea = {0}, unlockArea = {0};
    126 
    127         TDB_LOG((tdb, TDB_DEBUG_TRACE, "fcntl_lock in pid %d, fd %d, lck_type %s, rw_type %s, offset %d, len %d\n",
    128                 getpid(), tdb->fd, lock_type(waitflag), read_type(rw), off, len));
    129        
    130         switch(off) {
    131         case OPEN_LOCK:
    132         case ACTIVE_LOCK:
    133         case TRANSACTION_LOCK:
    134                 return _mutex_brlock(tdb, off, rw, waitflag, len);
    135         }
    136 
    137         /* flags and order */
    138         switch (rw)
    139         {
    140                 case F_UNLCK:
    141                         unlockArea.lOffset = off;
    142                         unlockArea.lRange  = len ? len : LONG_MAX;
    143                         break;
    144                 case F_RDLCK:
    145                         lockArea.lOffset = off;
    146                         lockArea.lRange  = len ? len : LONG_MAX;
    147                         fAccess = 1; /* read-only */
    148                         break;
    149                 case F_WRLCK:
    150                         lockArea.lOffset = off;
    151                         lockArea.lRange  = len ? len : LONG_MAX;
    152                         break;
    153                 default:
    154                         break;
    155         }
    156                
    157         rc = DosSetFileLocks(tdb->fd, &unlockArea, &lockArea, SEM_IMMEDIATE_RETURN, fAccess);
    158 
    159         if (rc != NO_ERROR && waitflag) {
    160                 int     count = 20;
    161                 do {
    162                         rc = DosSetFileLocks(tdb->fd, &unlockArea, &lockArea, 100, fAccess);
    163                         count--;
    164                 } while( count>0 && rc !=NO_ERROR);
    165 
    166         }
    167 
    168         TDB_LOG(( tdb, TDB_DEBUG_TRACE, "fcntl_lock out pid %d, fd %d, lck_type %s, rw_type %s, offset %d, len %d, rc=%d\n",
    169                 getpid(), tdb->fd, lock_type(waitflag), read_type(rw), off, len, rc));
    170 
    171         if (rc != NO_ERROR) {
    172                 errno  = EINVAL;
    173                 return -1;
    174         }
    175         return 0;
    176 #else
     36                      int rw, off_t off, off_t len, bool waitflag)
     37{
    17738        struct flock fl;
    17839
     
    18041        fl.l_whence = SEEK_SET;
    18142        fl.l_start = off;
     43#ifdef __OS2__
     44        fl.l_len = len ? len:LONG_MAX;
     45#else
    18246        fl.l_len = len;
     47#endif
    18348        fl.l_pid = 0;
    18449
     
    18752        else
    18853                return fcntl(tdb->fd, F_SETLK, &fl);
    189 #endif
    190 }
    191 
    192 static int fcntl_unlock(struct tdb_context *tdb, int rw, tdb_off_t off, size_t len)
     54}
     55
     56static int fcntl_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len)
    19357{
    19458        struct flock fl;
     
    254118        fl.l_whence = SEEK_SET;
    255119        fl.l_start = off;
     120#ifdef __OS2__
     121        fl.l_len = len ? len:LONG_MAX;
     122#else
    256123        fl.l_len = len;
     124#endif
    257125        fl.l_pid = 0;
     126
    258127#ifdef __OS2__
    259         int rc = 0;
    260         rc = fcntl_lock(tdb, F_UNLCK, off, len, 1);
     128        int rc = fcntl(tdb->fd, F_SETLKW, &fl);
    261129        // if the first unlock doesn't work and it's a complete unlock,
    262130        // we split it in 2 parts. first hash size*4 and then the rest
    263131        // as it was locked that way as well. and it seems fcntl() doesn't care
    264132        if (rc != 0 && off == FREELIST_TOP && len == 0) {
    265                 rc = fcntl_lock(tdb, F_UNLCK, off, tdb->header.hash_size *4, 1);
    266                 if (rc == 0)
    267                         rc = fcntl_lock(tdb, F_UNLCK, (off + tdb->header.hash_size *4), len, 1);
     133                fl.l_len = tdb->header.hash_size * 4;
     134                rc = fcntl(tdb->fd, F_SETLKW, &fl);
     135                if (rc == 0) {
     136                        fl.l_start = off + tdb->header.hash_size * 4;
     137                        fl.l_len = LONG_MAX;
     138                        rc = fcntl(tdb->fd, F_SETLKW, &fl);
     139                }
    268140        }
    269141        return rc;
     
    376248        while (count--) {
    377249                struct timeval tv;
    378 #ifdef __OS2__
    379                 // YD we cannot upgrade without an unlock first...
    380                 tdb_brlock(tdb, F_UNLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE);
    381 #endif
    382250                if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0,
    383251                               TDB_LOCK_WAIT|TDB_LOCK_PROBE) == 0) {
Note: See TracChangeset for help on using the changeset viewer.