Changeset 857


Ignore:
Timestamp:
Mar 18, 2014, 4:51:05 PM (11 years ago)
Author:
Silvan Scherrer
Message:

Samba 3.6: remove mutex sem and do it with a filelock

Location:
trunk/server/lib/tdb/common
Files:
4 edited

Legend:

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

    r848 r857  
    9898        // is a write lock: do not wait for lock.
    9999        // so this is what we try here:
    100         // 1. add a write lock and see if it works
     100        // 1. add a write lock and see it it works
    101101        // 2. if the write lock wasn't set, we try to unlock the segment
    102         //    first and add the write lock afterwards
     102        //    first and add the write lock afterwards
     103        // 3. we remove the write lock further down
     104        // 4. we might add the removed lock from step #2 again
    103105        int upgradeLockRC = 0;
     106        int unlockRC = -1;
    104107        upgradeLockRC = tdb_brlock(tdb, F_WRLCK, off, len, TDB_LOCK_NOWAIT);
    105108        if (upgradeLockRC != 0) {
    106                 tdb_brunlock(tdb, F_RDLCK, off, len);
     109                unlockRC = tdb_brunlock(tdb, F_RDLCK, off, len);
    107110                upgradeLockRC = tdb_brlock(tdb, F_WRLCK, off, len, TDB_LOCK_NOWAIT);
    108111        }
  • trunk/server/lib/tdb/common/lock.c

    r846 r857  
    3232        tdb->interrupt_sig_ptr = ptr;
    3333}
    34 
    35 #ifdef __OS2__
    36 static int handle_mutex_lock(struct tdb_context *tdb, HMTX mutex, int rw, bool waitflag)
    37 {
    38         ULONG   ulTimeout;
    39         APIRET  rc;
    40 
    41         if (mutex == 0) {
    42                 printf( "fcntl_lock: sem not initialised\n");
    43                 exit(1);
    44         }
    45 
    46         if (waitflag)
    47                 ulTimeout = SEM_INDEFINITE_WAIT;
    48         else
    49                 ulTimeout = SEM_IMMEDIATE_RETURN;
    50 
    51         switch (rw) {
    52         case F_UNLCK:
    53                 rc = DosReleaseMutexSem(mutex);
    54                 break;
    55         case F_RDLCK: // we never wait for a read lock, as several want to hold one
    56                 rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
    57                 if (rc == ERROR_NOT_OWNER || ERROR_TIMEOUT)
    58                         rc = NO_ERROR;
    59                 break;
    60         case F_WRLCK:
    61                 rc = DosRequestMutexSem(mutex, ulTimeout);
    62                 break;
    63         }
    64 
    65         if (rc == NO_ERROR || rc == ERROR_SEM_OWNER_DIED)
    66                 return 0;
    67 
    68         TDB_LOG((tdb, TDB_DEBUG_TRACE,"handle_mutex_lock: (fd=%d) rw_type=%d waitflag=%d (rc=%d)\n",
    69                 tdb->fd, rw, waitflag, rc));
    70 
    71         errno = EINVAL;
    72         return -1;
    73 }
    74 #endif
    7534
    7635static int fcntl_lock(struct tdb_context *tdb,
     
    9150#ifdef __OS2__
    9251        int rc = 0;
    93 
    94         if (off == ACTIVE_LOCK) {
    95                 rc = handle_mutex_lock(tdb, tdb->hActiveLock, rw, waitflag);
    96         } else {
    97                 int cmd = 0;
    98                 if (waitflag)
    99                         cmd = F_SETLKW;
    100                 else
    101                         cmd = F_SETLK;
    102 
    103                 rc = fcntl(tdb->fd, cmd, &fl);
    104                 // if the first lock doesn't work and it's a complete lock,
    105                 // we split it in 2 parts. first hash size*4 and then the rest
    106                 if (rc != 0 && off == FREELIST_TOP && len == 0) {
    107                         fl.l_len = tdb->header.hash_size * 4;
    108                         rc = fcntl(tdb->fd, cmd, &fl);
    109                         if (rc == 0) {
    110                                 fl.l_start = off + tdb->header.hash_size * 4;
    111                                 fl.l_len = LONG_MAX;
    112                                 rc = fcntl(tdb->fd, cmd, &fl);
    113                         }
     52        int lockFile = 0;
     53
     54        if (off == ACTIVE_LOCK)
     55                lockFile = tdb->hActiveLock;
     56        else
     57                lockFile = tdb->fd;
     58
     59        int cmd = 0;
     60        if (waitflag)
     61                cmd = F_SETLKW;
     62        else
     63                cmd = F_SETLK;
     64
     65        rc = fcntl(lockFile, cmd, &fl);
     66        // if the first lock doesn't work and it's a complete lock,
     67        // we split it in 2 parts. first hash size*4 and then the rest
     68        if (rc != 0 && off == FREELIST_TOP && len == 0) {
     69                fl.l_len = tdb->header.hash_size * 4;
     70                rc = fcntl(lockFile, cmd, &fl);
     71                if (rc == 0) {
     72                        fl.l_start = off + tdb->header.hash_size * 4;
     73                        fl.l_len = LONG_MAX;
     74                        rc = fcntl(lockFile, cmd, &fl);
    11475                }
    11576        }
     
    200161#ifdef __OS2__
    201162        int rc = 0;
    202         if (off == ACTIVE_LOCK) {
    203                 rc = handle_mutex_lock(tdb, tdb->hActiveLock, F_UNLCK, 1);
    204         } else {
    205                 rc = fcntl(tdb->fd, F_SETLKW, &fl);
    206                 // if the first unlock doesn't work and it's a complete unlock,
    207                 // we split it in 2 parts. first hash size*4 and then the rest
    208                 // as it was locked that way as well. and it seems fcntl() doesn't care
    209                 if (rc != 0 && off == FREELIST_TOP && len == 0) {
    210                         fl.l_len = tdb->header.hash_size * 4;
    211                         rc = fcntl(tdb->fd, F_SETLKW, &fl);
    212                         if (rc == 0) {
    213                                 fl.l_start = off + tdb->header.hash_size * 4;
    214                                 fl.l_len = LONG_MAX;
    215                                 rc = fcntl(tdb->fd, F_SETLKW, &fl);
    216                         }
     163        int lockFile = 0;
     164        if (off == ACTIVE_LOCK)
     165                lockFile = tdb->hActiveLock;
     166        else
     167                lockFile = tdb->fd;
     168
     169        rc = fcntl(lockFile, F_SETLKW, &fl);
     170        // if the first unlock doesn't work and it's a complete unlock,
     171        // we split it in 2 parts. first hash size*4 and then the rest
     172        // as it was locked that way as well. and it seems fcntl() doesn't care
     173        if (rc != 0 && off == FREELIST_TOP && len == 0) {
     174                fl.l_len = tdb->header.hash_size * 4;
     175                rc = fcntl(lockFile, F_SETLKW, &fl);
     176                if (rc == 0) {
     177                        fl.l_start = off + tdb->header.hash_size * 4;
     178                        fl.l_len = LONG_MAX;
     179                        rc = fcntl(lockFile, F_SETLKW, &fl);
    217180                }
    218181        }
  • trunk/server/lib/tdb/common/open.c

    r846 r857  
    293293        }
    294294
    295 #ifdef __OS2__
    296         if (os2_crtSem(tdb, name, "tdb_open_ex") != 0)
    297                 goto fail;
    298 #endif
    299 
    300295        if ((tdb->fd = open(name, open_flags, mode)) == -1) {
    301296                TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n",
     
    314309                goto fail;      /* errno set by tdb_brlock */
    315310        }
     311
     312#ifdef __OS2__
     313        if (os2_crtActiveLock(tdb, name, 1, mode) != 0)
     314                goto fail;
     315#endif
    316316
    317317        /* we need to zero database if we are the only one with it open */
     
    476476
    477477#ifdef __OS2__
    478         DosCloseMutexSem(tdb->hActiveLock);
    479         tdb->hActiveLock = 0;
     478        close(tdb->hActiveLock);
     479        tdb->hActiveLock = -1;
    480480#endif
    481481        if (!tdb)
     
    548548
    549549#ifdef __OS2__
    550         DosCloseMutexSem(tdb->hActiveLock);
    551         tdb->hActiveLock = 0;
     550        close(tdb->hActiveLock);
     551        tdb->hActiveLock = -1;
    552552#endif
    553553
     
    620620
    621621#ifdef __OS2__
    622         DosCloseMutexSem(tdb->hActiveLock);
    623         tdb->hActiveLock = 0;
    624 
    625         if (os2_crtSem(tdb, tdb->name, "tdb_reopen") != 0)
     622        close(tdb->hActiveLock);
     623        tdb->hActiveLock = -1;
     624
     625        if (os2_crtActiveLock(tdb, tdb->name, 0, 0) != 0)
    626626                goto fail;
    627627#endif
     
    680680}
    681681#ifdef __OS2__
    682 int os2_crtSem(struct tdb_context *tdb, const char *name, const char *caller)
     682int os2_crtActiveLock(struct tdb_context *tdb, const char *name, const int truncate, const int mode)
    683683{
    684684        // name could be null, so handle it
     
    686686                return -1;
    687687
    688         char    szSem[_MAX_PATH];
    689         char    drive[_MAX_DRIVE], dir[_MAX_DIR];
    690         char    fname[_MAX_FNAME], ext[_MAX_EXT];
    691         APIRET  rc;
    692         // extract path info
    693         _splitpath(name, drive, dir, fname, ext);
    694         sprintf(szSem, "\\SEM32\\TDB_AL_%s%s%s", dir, fname, ext);
    695         rc = DosCreateMutexSem(szSem, &tdb->hActiveLock, 0, FALSE);
    696         if (rc == ERROR_DUPLICATE_NAME)
    697                 rc = DosOpenMutexSem(szSem, &tdb->hActiveLock);
    698         if (rc != NO_ERROR) {
    699                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "os2_crtSem: cannot create sem32 %s (rc=%d) called from %s\n",
    700                         szSem, rc, caller));
     688        char activeLockName[_MAX_PATH];
     689        sprintf(activeLockName, "%s_AL", name);
     690        tdb->hActiveLock = open(activeLockName, tdb->open_flags, mode);
     691        if (tdb->hActiveLock == -1) {
     692                TDB_LOG((tdb, TDB_DEBUG_ERROR, "os2_crtSem: cannot create activeLock %s called from %s\n",
     693                        activeLockName, truncate?"tdb_open_ex":"tdb_reopen"));
    701694                errno = EINVAL;
    702695                return -1;
    703696        }
     697
     698        if (truncate) {
     699                if (lseek(tdb->hActiveLock, 0, SEEK_SET) == -1)
     700                        return -1;
     701
     702                if (ftruncate(tdb->hActiveLock, 0) == -1)
     703                        return -1;
     704
     705                tdb_write_all(tdb->hActiveLock, "used for active lock\n", 21);
     706        }
     707
    704708        return 0;
    705709}
  • trunk/server/lib/tdb/common/tdb_private.h

    r846 r857  
    220220        volatile sig_atomic_t *interrupt_sig_ptr;
    221221#ifdef __OS2__
    222         HMTX    hActiveLock;
     222        int hActiveLock;
    223223#endif
    224224};
Note: See TracChangeset for help on using the changeset viewer.