sdbm_lock.c revision 251876
1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251876Speter * contributor license agreements. See the NOTICE file distributed with 3251876Speter * this work for additional information regarding copyright ownership. 4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251876Speter * (the "License"); you may not use this file except in compliance with 6251876Speter * the License. You may obtain a copy of the License at 7251876Speter * 8251876Speter * http://www.apache.org/licenses/LICENSE-2.0 9251876Speter * 10251876Speter * Unless required by applicable law or agreed to in writing, software 11251876Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251876Speter * See the License for the specific language governing permissions and 14251876Speter * limitations under the License. 15251876Speter */ 16251876Speter 17251876Speter#include "apr_file_info.h" 18251876Speter#include "apr_file_io.h" 19251876Speter#include "apr_sdbm.h" 20251876Speter 21251876Speter#include "sdbm_private.h" 22251876Speter#include "sdbm_tune.h" 23251876Speter 24251876Speter/* NOTE: this function may block until it acquires the lock */ 25251876SpeterAPU_DECLARE(apr_status_t) apr_sdbm_lock(apr_sdbm_t *db, int type) 26251876Speter{ 27251876Speter apr_status_t status; 28251876Speter int lock_type = type & APR_FLOCK_TYPEMASK; 29251876Speter 30251876Speter if (!(lock_type == APR_FLOCK_SHARED || lock_type == APR_FLOCK_EXCLUSIVE)) 31251876Speter return APR_EINVAL; 32251876Speter 33251876Speter if (db->flags & SDBM_EXCLUSIVE_LOCK) { 34251876Speter ++db->lckcnt; 35251876Speter return APR_SUCCESS; 36251876Speter } 37251876Speter else if (db->flags & SDBM_SHARED_LOCK) { 38251876Speter /* 39251876Speter * Cannot promote a shared lock to an exlusive lock 40251876Speter * in a cross-platform compatibile manner. 41251876Speter */ 42251876Speter if (type == APR_FLOCK_EXCLUSIVE) 43251876Speter return APR_EINVAL; 44251876Speter ++db->lckcnt; 45251876Speter return APR_SUCCESS; 46251876Speter } 47251876Speter /* 48251876Speter * zero size: either a fresh database, or one with a single, 49251876Speter * unsplit data page: dirpage is all zeros. 50251876Speter */ 51251876Speter if ((status = apr_file_lock(db->dirf, type)) == APR_SUCCESS) 52251876Speter { 53251876Speter apr_finfo_t finfo; 54251876Speter if ((status = apr_file_info_get(&finfo, APR_FINFO_SIZE, db->dirf)) 55251876Speter != APR_SUCCESS) { 56251876Speter (void) apr_file_unlock(db->dirf); 57251876Speter return status; 58251876Speter } 59251876Speter 60251876Speter SDBM_INVALIDATE_CACHE(db, finfo); 61251876Speter 62251876Speter ++db->lckcnt; 63251876Speter if (type == APR_FLOCK_SHARED) 64251876Speter db->flags |= SDBM_SHARED_LOCK; 65251876Speter else if (type == APR_FLOCK_EXCLUSIVE) 66251876Speter db->flags |= SDBM_EXCLUSIVE_LOCK; 67251876Speter } 68251876Speter return status; 69251876Speter} 70251876Speter 71251876SpeterAPU_DECLARE(apr_status_t) apr_sdbm_unlock(apr_sdbm_t *db) 72251876Speter{ 73251876Speter if (!(db->flags & (SDBM_SHARED_LOCK | SDBM_EXCLUSIVE_LOCK))) 74251876Speter return APR_EINVAL; 75251876Speter if (--db->lckcnt > 0) 76251876Speter return APR_SUCCESS; 77251876Speter db->flags &= ~(SDBM_SHARED_LOCK | SDBM_EXCLUSIVE_LOCK); 78251876Speter return apr_file_unlock(db->dirf); 79251876Speter} 80