void tdb_setalarm_sigptr | ( | struct tdb_context * | tdb, | |
volatile sig_atomic_t * | ptr | |||
) |
参照先 tdb_context::interrupt_sig_ptr・tdb.
参照元 tdb_chainlock_with_timeout_internal().
00032 { 00033 tdb->interrupt_sig_ptr = ptr; 00034 }
int tdb_brlock | ( | struct tdb_context * | tdb, | |
tdb_off_t | offset, | |||
int | rw_type, | |||
int | lck_type, | |||
int | probe, | |||
size_t | len | |||
) |
参照先 tdb_context::ecode・errno・tdb_context::fd・tdb_context::flags・tdb_context::interrupt_sig_ptr・tdb_context::read_only・tdb・TDB_DEBUG_TRACE・TDB_ERR_LOCK・TDB_ERR_RDONLY・tdb_context::traverse_read.
参照元 tdb_brlock_upgrade()・tdb_increment_seqnum()・tdb_transaction_cancel()・tdb_transaction_commit()・tdb_transaction_start().
00046 { 00047 struct flock fl; 00048 int ret; 00049 00050 if (tdb->flags & TDB_NOLOCK) { 00051 return 0; 00052 } 00053 00054 if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) { 00055 tdb->ecode = TDB_ERR_RDONLY; 00056 return -1; 00057 } 00058 00059 fl.l_type = rw_type; 00060 fl.l_whence = SEEK_SET; 00061 fl.l_start = offset; 00062 fl.l_len = len; 00063 fl.l_pid = 0; 00064 00065 do { 00066 ret = fcntl(tdb->fd,lck_type,&fl); 00067 00068 /* Check for a sigalarm break. */ 00069 if (ret == -1 && errno == EINTR && 00070 tdb->interrupt_sig_ptr && 00071 *tdb->interrupt_sig_ptr) { 00072 break; 00073 } 00074 } while (ret == -1 && errno == EINTR); 00075 00076 if (ret == -1) { 00077 /* Generic lock error. errno set by fcntl. 00078 * EAGAIN is an expected return from non-blocking 00079 * locks. */ 00080 if (!probe && lck_type != F_SETLK) { 00081 /* Ensure error code is set for log fun to examine. */ 00082 tdb->ecode = TDB_ERR_LOCK; 00083 TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n", 00084 tdb->fd, offset, rw_type, lck_type, (int)len)); 00085 } 00086 return TDB_ERRCODE(TDB_ERR_LOCK, -1); 00087 } 00088 return 0; 00089 }
int tdb_brlock_upgrade | ( | struct tdb_context * | tdb, | |
tdb_off_t | offset, | |||
size_t | len | |||
) |
参照先 errno・tdb・tdb_brlock()・TDB_DEBUG_TRACE.
00099 { 00100 int count = 1000; 00101 while (count--) { 00102 struct timeval tv; 00103 if (tdb_brlock(tdb, offset, F_WRLCK, F_SETLKW, 1, len) == 0) { 00104 return 0; 00105 } 00106 if (errno != EDEADLK) { 00107 break; 00108 } 00109 /* sleep for as short a time as we can - more portable than usleep() */ 00110 tv.tv_sec = 0; 00111 tv.tv_usec = 1; 00112 select(0, NULL, NULL, NULL, &tv); 00113 } 00114 TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock_upgrade failed at offset %d\n", offset)); 00115 return -1; 00116 }
int tdb_lock | ( | struct tdb_context * | tdb, | |
int | list, | |||
int | ltype | |||
) |
参照先 tdb_lock_type::count・tdb_context::flags・tdb_context::global_lock・tdb_header::hash_size・tdb_context::header・tdb_lock_type::list・tdb_context::lockrecs・tdb_lock_type::ltype・tdb_context::num_lockrecs・tdb・TDB_DEBUG_ERROR・TDB_ERR_LOCK.
参照元 tdb_allocate()・tdb_append()・tdb_chainlock()・tdb_chainlock_read()・tdb_delete_hash()・tdb_dump_chain()・tdb_expand()・tdb_find_lock_hash()・tdb_free()・tdb_next_lock()・tdb_nextkey()・tdb_printfreelist()・tdb_purge_dead()・tdb_store()・tdb_validate_freelist().
00121 { 00122 struct tdb_lock_type *new_lck; 00123 int i; 00124 00125 /* a global lock allows us to avoid per chain locks */ 00126 if (tdb->global_lock.count && 00127 (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) { 00128 return 0; 00129 } 00130 00131 if (tdb->global_lock.count) { 00132 return TDB_ERRCODE(TDB_ERR_LOCK, -1); 00133 } 00134 00135 if (list < -1 || list >= (int)tdb->header.hash_size) { 00136 TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid list %d for ltype=%d\n", 00137 list, ltype)); 00138 return -1; 00139 } 00140 if (tdb->flags & TDB_NOLOCK) 00141 return 0; 00142 00143 for (i=0; i<tdb->num_lockrecs; i++) { 00144 if (tdb->lockrecs[i].list == list) { 00145 if (tdb->lockrecs[i].count == 0) { 00146 /* 00147 * Can't happen, see tdb_unlock(). It should 00148 * be an assert. 00149 */ 00150 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock: " 00151 "lck->count == 0 for list %d", list)); 00152 } 00153 /* 00154 * Just increment the in-memory struct, posix locks 00155 * don't stack. 00156 */ 00157 tdb->lockrecs[i].count++; 00158 return 0; 00159 } 00160 } 00161 00162 new_lck = (struct tdb_lock_type *)realloc( 00163 tdb->lockrecs, 00164 sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); 00165 if (new_lck == NULL) { 00166 errno = ENOMEM; 00167 return -1; 00168 } 00169 tdb->lockrecs = new_lck; 00170 00171 /* Since fcntl locks don't nest, we do a lock for the first one, 00172 and simply bump the count for future ones */ 00173 if (tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, 00174 0, 1)) { 00175 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " 00176 "ltype=%d (%s)\n", list, ltype, strerror(errno))); 00177 return -1; 00178 } 00179 00180 tdb->num_locks++; 00181 00182 tdb->lockrecs[tdb->num_lockrecs].list = list; 00183 tdb->lockrecs[tdb->num_lockrecs].count = 1; 00184 tdb->lockrecs[tdb->num_lockrecs].ltype = ltype; 00185 tdb->num_lockrecs += 1; 00186 00187 return 0; 00188 }
int tdb_unlock | ( | struct tdb_context * | tdb, | |
int | list, | |||
int | ltype | |||
) |
参照先 tdb_lock_type::count・tdb_context::flags・tdb_context::global_lock・tdb_header::hash_size・tdb_context::header・tdb_lock_type::list・tdb_context::lockrecs・tdb_lock_type::ltype・tdb_context::num_lockrecs・tdb・TDB_DEBUG_ERROR・TDB_ERR_LOCK.
参照元 tdb_allocate()・tdb_append()・tdb_chainunlock()・tdb_chainunlock_read()・tdb_delete_hash()・tdb_dump_chain()・tdb_exists_hash()・tdb_expand()・tdb_fetch()・tdb_find_lock_hash()・tdb_firstkey()・tdb_free()・tdb_next_lock()・tdb_nextkey()・tdb_parse_record()・tdb_printfreelist()・tdb_purge_dead()・tdb_store()・tdb_traverse_internal()・tdb_validate_freelist().
00194 { 00195 int ret = -1; 00196 int i; 00197 struct tdb_lock_type *lck = NULL; 00198 00199 /* a global lock allows us to avoid per chain locks */ 00200 if (tdb->global_lock.count && 00201 (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) { 00202 return 0; 00203 } 00204 00205 if (tdb->global_lock.count) { 00206 return TDB_ERRCODE(TDB_ERR_LOCK, -1); 00207 } 00208 00209 if (tdb->flags & TDB_NOLOCK) 00210 return 0; 00211 00212 /* Sanity checks */ 00213 if (list < -1 || list >= (int)tdb->header.hash_size) { 00214 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); 00215 return ret; 00216 } 00217 00218 for (i=0; i<tdb->num_lockrecs; i++) { 00219 if (tdb->lockrecs[i].list == list) { 00220 lck = &tdb->lockrecs[i]; 00221 break; 00222 } 00223 } 00224 00225 if ((lck == NULL) || (lck->count == 0)) { 00226 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n")); 00227 return -1; 00228 } 00229 00230 if (lck->count > 1) { 00231 lck->count--; 00232 return 0; 00233 } 00234 00235 /* 00236 * This lock has count==1 left, so we need to unlock it in the 00237 * kernel. We don't bother with decrementing the in-memory array 00238 * element, we're about to overwrite it with the last array element 00239 * anyway. 00240 */ 00241 00242 ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, 00243 F_SETLKW, 0, 1); 00244 tdb->num_locks--; 00245 00246 /* 00247 * Shrink the array by overwriting the element just unlocked with the 00248 * last array element. 00249 */ 00250 00251 if (tdb->num_lockrecs > 1) { 00252 *lck = tdb->lockrecs[tdb->num_lockrecs-1]; 00253 } 00254 tdb->num_lockrecs -= 1; 00255 00256 /* 00257 * We don't bother with realloc when the array shrinks, but if we have 00258 * a completely idle tdb we should get rid of the locked array. 00259 */ 00260 00261 if (tdb->num_lockrecs == 0) { 00262 SAFE_FREE(tdb->lockrecs); 00263 } 00264 00265 if (ret) 00266 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); 00267 return ret; 00268 }
static int _tdb_lockall | ( | struct tdb_context * | tdb, | |
int | ltype | |||
) | [static] |
参照先 tdb_lock_type::count・errno・tdb_context::global_lock・tdb_header::hash_size・tdb_context::header・tdb_lock_type::ltype・tdb_context::methods・tdb_context::num_locks・tdb_context::read_only・strerror()・tdb・tdb_methods::tdb_brlock・TDB_DEBUG_ERROR・TDB_ERR_LOCK・tdb_context::traverse_read.
参照元 tdb_lockall()・tdb_lockall_read().
00274 { 00275 /* There are no locks on read-only dbs */ 00276 if (tdb->read_only || tdb->traverse_read) 00277 return TDB_ERRCODE(TDB_ERR_LOCK, -1); 00278 00279 if (tdb->global_lock.count && tdb->global_lock.ltype == ltype) { 00280 tdb->global_lock.count++; 00281 return 0; 00282 } 00283 00284 if (tdb->global_lock.count) { 00285 /* a global lock of a different type exists */ 00286 return TDB_ERRCODE(TDB_ERR_LOCK, -1); 00287 } 00288 00289 if (tdb->num_locks != 0) { 00290 /* can't combine global and chain locks */ 00291 return TDB_ERRCODE(TDB_ERR_LOCK, -1); 00292 } 00293 00294 if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, F_SETLKW, 00295 0, 4*tdb->header.hash_size)) { 00296 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno))); 00297 return -1; 00298 } 00299 00300 tdb->global_lock.count = 1; 00301 tdb->global_lock.ltype = ltype; 00302 00303 return 0; 00304 }
static int _tdb_unlockall | ( | struct tdb_context * | tdb, | |
int | ltype | |||
) | [static] |
参照先 tdb_lock_type::count・errno・tdb_context::global_lock・tdb_header::hash_size・tdb_context::header・tdb_lock_type::ltype・tdb_context::methods・tdb_context::read_only・strerror()・tdb・tdb_methods::tdb_brlock・TDB_DEBUG_ERROR・TDB_ERR_LOCK・tdb_context::traverse_read.
参照元 tdb_unlockall()・tdb_unlockall_read().
00308 { 00309 /* There are no locks on read-only dbs */ 00310 if (tdb->read_only || tdb->traverse_read) { 00311 return TDB_ERRCODE(TDB_ERR_LOCK, -1); 00312 } 00313 00314 if (tdb->global_lock.ltype != ltype || tdb->global_lock.count == 0) { 00315 return TDB_ERRCODE(TDB_ERR_LOCK, -1); 00316 } 00317 00318 if (tdb->global_lock.count > 1) { 00319 tdb->global_lock.count--; 00320 return 0; 00321 } 00322 00323 if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 00324 0, 4*tdb->header.hash_size)) { 00325 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno))); 00326 return -1; 00327 } 00328 00329 tdb->global_lock.count = 0; 00330 tdb->global_lock.ltype = 0; 00331 00332 return 0; 00333 }
int tdb_lockall | ( | struct tdb_context * | tdb | ) |
参照先 _tdb_lockall()・tdb.
参照元 backup_tdb()・load_msg()・py_tdb_hnd_lock_all().
00337 { 00338 return _tdb_lockall(tdb, F_WRLCK); 00339 }
int tdb_unlockall | ( | struct tdb_context * | tdb | ) |
参照先 _tdb_unlockall()・tdb.
参照元 load_msg()・py_tdb_hnd_unlock_all().
00343 { 00344 return _tdb_unlockall(tdb, F_WRLCK); 00345 }
int tdb_lockall_read | ( | struct tdb_context * | tdb | ) |
int tdb_unlockall_read | ( | struct tdb_context * | tdb | ) |
int tdb_chainlock | ( | struct tdb_context * | tdb, | |
TDB_DATA | key | |||
) |
参照先 tdb_context::hash_fn・tdb・tdb_lock().
参照元 addrec_db()・brl_get_locks_internal()・get_share_mode_lock()・idmap_tdb_remove_mapping()・idmap_tdb_set_mapping()・message_send_pid_internal()・py_tdb_hnd_chainlock()・retrieve_all_messages()・smb_lock_share_mode_entry()・tdb_chainlock_with_timeout_internal()・tdb_lock_bystring().
int tdb_chainunlock | ( | struct tdb_context * | tdb, | |
TDB_DATA | key | |||
) |
参照先 tdb_context::hash_fn・tdb・tdb_unlock().
参照元 addrec_db()・byte_range_lock_destructor()・idmap_tdb_remove_mapping()・idmap_tdb_set_mapping()・message_send_pid_internal()・py_tdb_hnd_chainunlock()・remove_from_jobs_changed()・retrieve_all_messages()・share_mode_lock_destructor()・smb_unlock_share_mode_entry()・tdb_unlock_bystring().
00367 { 00368 return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); 00369 }
int tdb_chainlock_read | ( | struct tdb_context * | tdb, | |
TDB_DATA | key | |||
) |
int tdb_chainunlock_read | ( | struct tdb_context * | tdb, | |
TDB_DATA | key | |||
) |
参照先 tdb_context::hash_fn・tdb・tdb_unlock().
参照元 tdb_read_unlock_bystring().
00377 { 00378 return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); 00379 }
int tdb_lock_record | ( | struct tdb_context * | tdb, | |
tdb_off_t | off | |||
) |
参照先 tdb_context::methods・tdb・tdb_methods::tdb_brlock.
参照元 tdb_next_lock()・tdb_nextkey().
00385 { 00386 return off ? tdb->methods->tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0, 1) : 0; 00387 }
int tdb_write_lock_record | ( | struct tdb_context * | tdb, | |
tdb_off_t | off | |||
) |
参照先 tdb_context::methods・tdb_traverse_lock::next・tdb_traverse_lock::off・tdb・tdb_methods::tdb_brlock・tdb_context::travlocks.
参照元 tdb_do_delete().
00395 { 00396 struct tdb_traverse_lock *i; 00397 for (i = &tdb->travlocks; i; i = i->next) 00398 if (i->off == off) 00399 return -1; 00400 return tdb->methods->tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1, 1); 00401 }
int tdb_write_unlock_record | ( | struct tdb_context * | tdb, | |
tdb_off_t | off | |||
) |
参照先 tdb_context::methods・tdb・tdb_methods::tdb_brlock.
参照元 tdb_do_delete().
00408 { 00409 return tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0, 1); 00410 }
int tdb_unlock_record | ( | struct tdb_context * | tdb, | |
tdb_off_t | off | |||
) |
参照先 tdb_context::methods・tdb_traverse_lock::next・tdb_traverse_lock::off・tdb・tdb_methods::tdb_brlock・tdb_context::travlocks.
参照元 tdb_firstkey()・tdb_next_lock()・tdb_nextkey()・tdb_traverse_internal().
00414 { 00415 struct tdb_traverse_lock *i; 00416 u32 count = 0; 00417 00418 if (off == 0) 00419 return 0; 00420 for (i = &tdb->travlocks; i; i = i->next) 00421 if (i->off == off) 00422 count++; 00423 return (count == 1 ? tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0, 1) : 0); 00424 }