sdbm_lock.c revision 256281
1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr_file_info.h" 18#include "apr_file_io.h" 19#include "apr_sdbm.h" 20 21#include "sdbm_private.h" 22#include "sdbm_tune.h" 23 24/* NOTE: this function may block until it acquires the lock */ 25APU_DECLARE(apr_status_t) apr_sdbm_lock(apr_sdbm_t *db, int type) 26{ 27 apr_status_t status; 28 int lock_type = type & APR_FLOCK_TYPEMASK; 29 30 if (!(lock_type == APR_FLOCK_SHARED || lock_type == APR_FLOCK_EXCLUSIVE)) 31 return APR_EINVAL; 32 33 if (db->flags & SDBM_EXCLUSIVE_LOCK) { 34 ++db->lckcnt; 35 return APR_SUCCESS; 36 } 37 else if (db->flags & SDBM_SHARED_LOCK) { 38 /* 39 * Cannot promote a shared lock to an exlusive lock 40 * in a cross-platform compatibile manner. 41 */ 42 if (type == APR_FLOCK_EXCLUSIVE) 43 return APR_EINVAL; 44 ++db->lckcnt; 45 return APR_SUCCESS; 46 } 47 /* 48 * zero size: either a fresh database, or one with a single, 49 * unsplit data page: dirpage is all zeros. 50 */ 51 if ((status = apr_file_lock(db->dirf, type)) == APR_SUCCESS) 52 { 53 apr_finfo_t finfo; 54 if ((status = apr_file_info_get(&finfo, APR_FINFO_SIZE, db->dirf)) 55 != APR_SUCCESS) { 56 (void) apr_file_unlock(db->dirf); 57 return status; 58 } 59 60 SDBM_INVALIDATE_CACHE(db, finfo); 61 62 ++db->lckcnt; 63 if (type == APR_FLOCK_SHARED) 64 db->flags |= SDBM_SHARED_LOCK; 65 else if (type == APR_FLOCK_EXCLUSIVE) 66 db->flags |= SDBM_EXCLUSIVE_LOCK; 67 } 68 return status; 69} 70 71APU_DECLARE(apr_status_t) apr_sdbm_unlock(apr_sdbm_t *db) 72{ 73 if (!(db->flags & (SDBM_SHARED_LOCK | SDBM_EXCLUSIVE_LOCK))) 74 return APR_EINVAL; 75 if (--db->lckcnt > 0) 76 return APR_SUCCESS; 77 db->flags &= ~(SDBM_SHARED_LOCK | SDBM_EXCLUSIVE_LOCK); 78 return apr_file_unlock(db->dirf); 79} 80