Changeset 905 for trunk/server/lib/tdb/common/lock.c
- Timestamp:
- May 19, 2016, 2:25:59 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server/lib/tdb/common/lock.c
r895 r905 33 33 } 34 34 35 #ifdef __OS2__36 enum os2_fl {37 OS2_FL_LOCK = 0x1,38 OS2_FL_RW = 0x2,39 OS2_FL_WAIT = 0x4,40 OS2_FL_UPGRADE = 0x8,41 };42 43 static int os2_set_file_locks(struct tdb_context *tdb, enum os2_fl flags,44 off_t start, off_t offset, off_t len)45 {46 FILELOCKL locks[2] = {0};47 ULONG fl;48 BOOL dowait;49 APIRET arc;50 51 if ((!(flags & OS2_FL_UPGRADE) && (start > offset || start < 0)) ||52 offset < 0 || offset + len < 0) {53 errno = EINVAL;54 return -1;55 }56 57 fl = (flags & OS2_FL_RW) ? 0 : 1; /* excluive when rw, shared otherwise */58 59 if (flags & OS2_FL_UPGRADE) {60 locks[0].lOffset = offset;61 locks[0].lRange = len == 0 ? OFF_MAX : len;62 locks[1] = locks[0];63 fl |= 2; /* atomic */64 } else {65 if (start != offset) {66 locks[0].lOffset = start;67 locks[0].lRange = offset - start;68 fl |= 2; /* atomic */69 }70 locks[1].lOffset = start;71 locks[1].lRange = len == 0 ? OFF_MAX : (locks[0].lRange + len);72 }73 74 dowait = (flags & (OS2_FL_LOCK | OS2_FL_UPGRADE)) && (flags & OS2_FL_WAIT);75 76 TDB_LOG((tdb, TDB_DEBUG_TRACE, "os2_file_locks: fd=%d lock_fd=%d flags=%x start=%lld offset=%lld len=%lld pid=%d\n",77 tdb->fd, tdb->lock_fd, flags, start, offset, len, getpid()));78 79 arc = DosSetFileLocksL(tdb->lock_fd,80 &locks[(flags & OS2_FL_LOCK) ? 0 : 1],81 &locks[(flags & OS2_FL_LOCK) ? 1 : 0],82 dowait ? SEM_INDEFINITE_WAIT : SEM_IMMEDIATE_RETURN,83 fl);84 85 TDB_LOG((tdb, TDB_DEBUG_TRACE, "os2_file_locks: arc=%d pid=%d\n", arc, getpid()));86 87 if (arc) {88 switch (arc) {89 case ERROR_LOCK_VIOLATION:90 errno = EACCES;91 break;92 case ERROR_INTERRUPT:93 errno = EINTR;94 break;95 case ERROR_TIMEOUT:96 errno = EDEADLK;97 break;98 default:99 TDB_LOG((tdb, TDB_DEBUG_ERROR, "os2_file_locks failed, lock_fd=%d flags=%x start=%d off=%d len=%d (arc=%d)\n",100 tdb->lock_fd, flags, start, offset, len, arc));101 }102 return -1;103 }104 105 return 0;106 }107 #else /* __OS2__ */108 35 static int fcntl_lock(struct tdb_context *tdb, 109 36 int rw, off_t off, off_t len, bool waitflag) … … 192 119 return fcntl(tdb->fd, F_SETLKW, &fl); 193 120 } 194 #endif /* __OS2__ */195 121 196 122 /* list -1 is the alloc list, otherwise a hash chain. */ … … 208 134 note that a len of zero means lock to end of file 209 135 */ 210 #ifdef __OS2__211 static int tdb_brlock_ex(struct tdb_context *tdb,212 int rw_type, tdb_off_t start,213 tdb_off_t offset, size_t len,214 enum tdb_lock_flags flags)215 #else216 136 int tdb_brlock(struct tdb_context *tdb, 217 137 int rw_type, tdb_off_t offset, size_t len, 218 138 enum tdb_lock_flags flags) 219 #endif220 139 { 221 140 int ret; … … 234 153 } 235 154 236 #ifdef __OS2__237 int os2_flags = OS2_FL_LOCK;238 if (rw_type == F_WRLCK) {239 os2_flags |= OS2_FL_RW;240 }241 if (flags & TDB_LOCK_WAIT) {242 os2_flags |= OS2_FL_WAIT;243 }244 if (flags & TDB_LOCK_UPGRADE) {245 os2_flags |= OS2_FL_UPGRADE;246 }247 #endif248 249 155 do { 250 #ifdef __OS2__251 ret = os2_set_file_locks(tdb, os2_flags, start, offset, len);252 #else253 156 ret = fcntl_lock(tdb, rw_type, offset, len, 254 157 flags & TDB_LOCK_WAIT); 255 #endif256 158 /* Check for a sigalarm break. */ 257 159 if (ret == -1 && errno == EINTR && … … 268 170 * locks. */ 269 171 if (!(flags & TDB_LOCK_PROBE) && errno != EAGAIN) { 270 TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d flags=%d len=%d (errno=%d)\n",271 tdb->fd, offset, rw_type, flags, (int)len , errno));172 TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d flags=%d len=%d\n", 173 tdb->fd, offset, rw_type, flags, (int)len)); 272 174 } 273 175 return -1; … … 276 178 } 277 179 278 #ifdef __OS2__279 int tdb_brlock(struct tdb_context *tdb,280 int rw_type, tdb_off_t offset, size_t len,281 enum tdb_lock_flags flags)282 {283 return tdb_brlock_ex(tdb, rw_type, offset, offset, len, flags);284 }285 #endif286 287 #ifdef __OS2__288 static int tdb_brunlock_ex(struct tdb_context *tdb,289 int rw_type, tdb_off_t start,290 tdb_off_t offset, size_t len)291 #else292 180 int tdb_brunlock(struct tdb_context *tdb, 293 181 int rw_type, tdb_off_t offset, size_t len) 294 #endif295 182 { 296 183 int ret; … … 301 188 302 189 do { 303 #ifdef __OS2__304 ret = os2_set_file_locks(tdb, rw_type == F_WRLCK ? OS2_FL_RW : 0,305 start, offset, len);306 #else307 190 ret = fcntl_unlock(tdb, rw_type, offset, len); 308 #endif309 191 } while (ret == -1 && errno == EINTR); 310 192 311 193 if (ret == -1) { 312 TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %d rw_type=%d len=%d (errno=%d)\n", 313 tdb->fd, offset, rw_type, (int)len, errno)); 314 } 315 return ret; 316 } 317 318 #ifdef __OS2__ 319 int tdb_brunlock(struct tdb_context *tdb, 320 int rw_type, tdb_off_t offset, size_t len) 321 { 322 return tdb_brunlock_ex(tdb, rw_type, offset, offset, len); 323 } 324 #endif 194 TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %d rw_type=%d len=%d\n", 195 tdb->fd, offset, rw_type, (int)len)); 196 } 197 return ret; 198 } 325 199 326 200 /* … … 350 224 struct timeval tv; 351 225 if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, 352 TDB_LOCK_WAIT|TDB_LOCK_PROBE |TDB_LOCK_UPGRADE) == 0) {226 TDB_LOCK_WAIT|TDB_LOCK_PROBE) == 0) { 353 227 tdb->allrecord_lock.ltype = F_WRLCK; 354 228 tdb->allrecord_lock.off = 0; … … 640 514 } 641 515 642 #ifdef __OS2__643 #define TDB_ADJLOCK_START_DECL size_t start,644 #define TDB_ADJLOCK_START start,645 #define TDB_ADJLOCK(tdb, rw_type, start, offset, len, flags) \646 tdb_brlock_ex(tdb, rw_type, start, offset, len, flags)647 #define TDB_ADJUNLOCK(tdb, rw_type, start, offset, len) \648 tdb_brunlock_ex(tdb, rw_type, start, offset, len)649 #define TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start, offset, len) \650 tdb_chainlock_gradual(tdb, ltype, flags, start, offset, len)651 #else652 #define TDB_ADJLOCK_START_DECL653 #define TDB_ADJLOCK_START_REF654 #define TDB_ADJLOCK(tdb, rw_type, start, offset, len, flags) \655 tdb_brlock(tdb, rw_type, offset, len, flags)656 #define TDB_ADJUNLOCK(tdb, rw_type, start, offset, len) \657 tdb_brunlock(tdb, rw_type, offset, len)658 #define TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start, offset, len) \659 tdb_chainlock_gradual(tdb, ltype, flags, offset, len)660 #endif661 662 516 /* We only need to lock individual bytes, but Linux merges consecutive locks 663 517 * so we lock in contiguous ranges. */ 664 518 static int tdb_chainlock_gradual(struct tdb_context *tdb, 665 519 int ltype, enum tdb_lock_flags flags, 666 TDB_ADJLOCK_START_DECLsize_t off, size_t len)520 size_t off, size_t len) 667 521 { 668 522 int ret; … … 671 525 if (len <= 4) { 672 526 /* Single record. Just do blocking lock. */ 673 return TDB_ADJLOCK(tdb, ltype, start, off, len, flags);527 return tdb_brlock(tdb, ltype, off, len, flags); 674 528 } 675 529 676 530 /* First we try non-blocking. */ 677 ret = TDB_ADJLOCK(tdb, ltype, start, off, len, nb_flags);531 ret = tdb_brlock(tdb, ltype, off, len, nb_flags); 678 532 if (ret == 0) { 679 533 return 0; … … 681 535 682 536 /* Try locking first half, then second. */ 683 ret = TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start, off, len / 2);537 ret = tdb_chainlock_gradual(tdb, ltype, flags, off, len / 2); 684 538 if (ret == -1) 685 539 return -1; 686 540 687 ret = TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start,541 ret = tdb_chainlock_gradual(tdb, ltype, flags, 688 542 off + len / 2, len - len / 2); 689 543 if (ret == -1) { 690 TDB_ADJUNLOCK(tdb, ltype, start, off, len / 2);544 tdb_brunlock(tdb, ltype, off, len / 2); 691 545 return -1; 692 546 } … … 714 568 * It is (1) which cause the starvation problem, so we're only 715 569 * gradual for that. */ 716 if ( TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, FREELIST_TOP, FREELIST_TOP,570 if (tdb_chainlock_gradual(tdb, ltype, flags, FREELIST_TOP, 717 571 tdb->header.hash_size * 4) == -1) { 718 572 return -1; … … 720 574 721 575 /* Grab individual record locks. */ 722 if ( TDB_ADJLOCK(tdb, ltype, FREELIST_TOP, lock_offset(tdb->header.hash_size), 0,723 576 if (tdb_brlock(tdb, ltype, lock_offset(tdb->header.hash_size), 0, 577 flags) == -1) { 724 578 tdb_brunlock(tdb, ltype, FREELIST_TOP, 725 579 tdb->header.hash_size * 4);
Note:
See TracChangeset
for help on using the changeset viewer.