/* * Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: adblimits.c,v 1.9 2006/03/13 18:41:30 ca Exp $") #include "sm/types.h" #include "sm/assert.h" #include "sm/magic.h" #include "sm/memops.h" #include "sm/actdb-int.h" /* ** AQ_RAISE_LIMIT -- Raise the limit (max. number of entries in AQ) ** ** Parameters: ** aq_ctx -- AQ context ** limit -- new limit; 0/UINT_MAX: raise it gradually/to the max ** locktype -- kind of locking ** ** Returns: ** usual sm_error code; SM_E_RANGE, (un)lock ** ** Last code review: 2005-04-16 04:45:56 ** Last code change: 2005-04-20 23:38:56 */ sm_ret_T aq_raise_limit(aq_ctx_P aq_ctx, uint limit, thr_lock_T locktype) { int r; sm_ret_T ret; SM_IS_AQ(aq_ctx); ret = SM_SUCCESS; if (thr_lock_it(locktype)) { r = pthread_mutex_lock(&aq_ctx->aq_mutex); SM_LOCK_OK(r); if (r != 0) return sm_error_perm(SM_EM_AQ, r); } if (limit == UINT_MAX) aq_ctx->aq_limit = aq_ctx->aq_max_entries; else if (limit == 0) { if (aq_ctx->aq_limit < aq_ctx->aq_max_entries) { uint d; d = aq_ctx->aq_max_entries - aq_ctx->aq_limit; if (d < 10) aq_ctx->aq_limit = aq_ctx->aq_max_entries; else { aq_ctx->aq_limit += d / 2; if (aq_ctx->aq_limit > aq_ctx->aq_max_entries) aq_ctx->aq_limit = aq_ctx->aq_max_entries; } } } else if (limit > aq_ctx->aq_limit && limit <= aq_ctx->aq_max_entries) aq_ctx->aq_limit = limit; else if (limit > aq_ctx->aq_max_entries) ret = sm_error_temp(SM_EM_AQ, SM_E_RANGE); if ((!sm_is_err(ret) && thr_unl_no_err(locktype)) || (sm_is_err(ret) && thr_unl_if_err(locktype))) { r = pthread_mutex_unlock(&aq_ctx->aq_mutex); SM_ASSERT(r == 0); if (r != 0 && sm_is_success(ret)) ret = sm_error_perm(SM_EM_AQ, r); } return ret; } /* ** AQ_LOWER_LIMIT -- Lower the limit (max. number of entries in AQ) ** ** Parameters: ** aq_ctx -- AQ context ** limit -- new limit, 0: use lowest possible value ** locktype -- kind of locking ** ** Returns: ** usual sm_error code; SM_E_RANGE, (un)lock ** ** Last code review: 2005-04-16 04:42:31 ** Last code change: */ #define MIN_AQ_ENTRIES 8 sm_ret_T aq_lower_limit(aq_ctx_P aq_ctx, uint limit, thr_lock_T locktype) { int r; sm_ret_T ret; SM_IS_AQ(aq_ctx); ret = SM_SUCCESS; if (thr_lock_it(locktype)) { r = pthread_mutex_lock(&aq_ctx->aq_mutex); SM_LOCK_OK(r); if (r != 0) return sm_error_perm(SM_EM_AQ, r); } if (limit != 0 && limit < MIN_AQ_ENTRIES) ret = sm_error_perm(SM_EM_AQ, SM_E_RANGE); else if (limit < aq_ctx->aq_limit) { if (limit >= aq_ctx->aq_entries) aq_ctx->aq_limit = limit; else aq_ctx->aq_limit = SM_MAX(aq_ctx->aq_entries, MIN_AQ_ENTRIES); } if ((!sm_is_err(ret) && thr_unl_no_err(locktype)) || (sm_is_err(ret) && thr_unl_if_err(locktype))) { r = pthread_mutex_unlock(&aq_ctx->aq_mutex); SM_ASSERT(r == 0); if (r != 0 && sm_is_success(ret)) ret = sm_error_perm(SM_EM_AQ, r); } return ret; } /* ** AQ_GET_LIMITS -- return various limits ** ** Parameters: ** aq_ctx -- AQ context ** pentries -- (pointer to) entries (output) ** plimit -- (pointer to) limit (output) ** pmax_entries -- (pointer to) max_entries (output) ** locktype -- kind of locking ** ** Returns: ** usual sm_error code; only (un)lock ** ** Last code review: 2005-04-16 04:50:02 ** Last code change: */ sm_ret_T aq_get_limits(aq_ctx_P aq_ctx, uint *pentries, uint *plimit, uint *pmax_entries, thr_lock_T locktype) { int r; sm_ret_T ret; SM_IS_AQ(aq_ctx); SM_REQUIRE(pentries != NULL); SM_REQUIRE(plimit != NULL); SM_REQUIRE(pmax_entries != NULL); ret = SM_SUCCESS; if (thr_lock_it(locktype)) { r = pthread_mutex_lock(&aq_ctx->aq_mutex); SM_LOCK_OK(r); if (r != 0) return sm_error_perm(SM_EM_AQ, r); } *pentries = aq_ctx->aq_entries; *plimit = aq_ctx->aq_limit; *pmax_entries = aq_ctx->aq_max_entries; if ((!sm_is_err(ret) && thr_unl_no_err(locktype)) || (sm_is_err(ret) && thr_unl_if_err(locktype))) { r = pthread_mutex_unlock(&aq_ctx->aq_mutex); SM_ASSERT(r == 0); if (r != 0 && sm_is_success(ret)) ret = sm_error_perm(SM_EM_AQ, r); } return ret; }