📄 seqmod.c
字号:
/* seqmod.c - sequenced modifies *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2004-2007 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. *//* ACKNOWLEDGEMENTS: * This work was initially developed by Howard Chu for inclusion in * OpenLDAP Software. */#include "portable.h"#ifdef SLAPD_OVER_SEQMOD#include "slap.h"/* This overlay serializes concurrent attempts to modify a single entry */typedef struct modtarget { struct modtarget *mt_next; struct modtarget *mt_tail; Operation *mt_op;} modtarget;typedef struct seqmod_info { Avlnode *sm_mods; /* entries being modified */ ldap_pvt_thread_mutex_t sm_mutex;} seqmod_info;static intsm_avl_cmp( const void *c1, const void *c2 ){ const modtarget *m1, *m2; int rc; m1 = c1; m2 = c2; rc = m1->mt_op->o_req_ndn.bv_len - m2->mt_op->o_req_ndn.bv_len; if ( rc ) return rc; return ber_bvcmp( &m1->mt_op->o_req_ndn, &m2->mt_op->o_req_ndn );}static intseqmod_op_cleanup( Operation *op, SlapReply *rs ){ slap_callback *sc = op->o_callback; seqmod_info *sm = sc->sc_private; modtarget *mt, mtdummy; Avlnode *av; mtdummy.mt_op = op; /* This op is done, remove it */ ldap_pvt_thread_mutex_lock( &sm->sm_mutex ); av = avl_find2( sm->sm_mods, &mtdummy, sm_avl_cmp ); assert(av != NULL); mt = av->avl_data; /* If there are more, promote the next one */ if ( mt->mt_next ) { av->avl_data = mt->mt_next; mt->mt_next->mt_tail = mt->mt_tail; } else { avl_delete( &sm->sm_mods, mt, sm_avl_cmp ); } ldap_pvt_thread_mutex_unlock( &sm->sm_mutex ); op->o_callback = sc->sc_next; op->o_tmpfree( sc, op->o_tmpmemctx ); return 0;}static intseqmod_op_mod( Operation *op, SlapReply *rs ){ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; seqmod_info *sm = on->on_bi.bi_private; modtarget *mt; Avlnode *av; slap_callback *cb; cb = op->o_tmpcalloc( 1, sizeof(slap_callback) + sizeof(modtarget), op->o_tmpmemctx ); mt = (modtarget *)(cb+1); mt->mt_next = NULL; mt->mt_tail = mt; mt->mt_op = op; /* See if we're already modifying this entry - don't allow * near-simultaneous mods of the same entry */ ldap_pvt_thread_mutex_lock( &sm->sm_mutex ); av = avl_find2( sm->sm_mods, mt, sm_avl_cmp ); if ( av ) { modtarget *mtp = av->avl_data; mtp->mt_tail->mt_next = mt; mtp->mt_tail = mt; /* Wait for this op to get to head of list */ while ( mtp != mt ) { ldap_pvt_thread_mutex_unlock( &sm->sm_mutex ); ldap_pvt_thread_yield(); /* Let it finish - should use a condition * variable here... */ ldap_pvt_thread_mutex_lock( &sm->sm_mutex ); mtp = av->avl_data; } } else { /* Record that we're modifying this now */ avl_insert( &sm->sm_mods, mt, sm_avl_cmp, avl_dup_error ); } ldap_pvt_thread_mutex_unlock( &sm->sm_mutex ); cb->sc_cleanup = seqmod_op_cleanup; cb->sc_private = sm; cb->sc_next = op->o_callback; op->o_callback = cb; return SLAP_CB_CONTINUE;}static intseqmod_op_extended( Operation *op, SlapReply *rs){ if ( exop_is_write( op )) return seqmod_op_mod( op, rs ); else return SLAP_CB_CONTINUE;}static intseqmod_db_open( BackendDB *be){ slap_overinst *on = (slap_overinst *)be->bd_info; seqmod_info *sm; sm = ch_calloc(1, sizeof(seqmod_info)); on->on_bi.bi_private = sm; ldap_pvt_thread_mutex_init( &sm->sm_mutex ); return 0;}static intseqmod_db_close( BackendDB *be){ slap_overinst *on = (slap_overinst *)be->bd_info; seqmod_info *sm = (seqmod_info *)on->on_bi.bi_private; if ( sm ) { ldap_pvt_thread_mutex_destroy( &sm->sm_mutex ); ch_free( sm ); } return 0;}/* This overlay is set up for dynamic loading via moduleload. For static * configuration, you'll need to arrange for the slap_overinst to be * initialized and registered by some other function inside slapd. */static slap_overinst seqmod;intseqmod_initialize(){ seqmod.on_bi.bi_type = "seqmod"; seqmod.on_bi.bi_db_open = seqmod_db_open; seqmod.on_bi.bi_db_close = seqmod_db_close; seqmod.on_bi.bi_op_modify = seqmod_op_mod; seqmod.on_bi.bi_op_modrdn = seqmod_op_mod; seqmod.on_bi.bi_extended = seqmod_op_extended; return overlay_register( &seqmod );}#if SLAPD_OVER_SEQMOD == SLAPD_MOD_DYNAMICintinit_module( int argc, char *argv[] ){ return seqmod_initialize();}#endif /* SLAPD_OVER_SEQMOD == SLAPD_MOD_DYNAMIC */#endif /* defined(SLAPD_OVER_SEQMOD) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -