X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibrewrite%2Fsession.c;h=4fa58f876c5664e0f04af10563b938e7d30f8963;hb=474dfbc8fd75aed0376695ccc2f8c092a7a1bc6f;hp=fa5c78354a682211ca80e85084c50c3ed3e2d5cf;hpb=4a8ab5dbf2ba037b0824d64bb3217ca06671884a;p=openldap diff --git a/libraries/librewrite/session.c b/libraries/librewrite/session.c index fa5c78354a..4fa58f876c 100644 --- a/libraries/librewrite/session.c +++ b/libraries/librewrite/session.c @@ -1,26 +1,21 @@ -/****************************************************************************** +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . * - * Copyright (C) 2000 Pierangelo Masarati, + * Copyright 2000-2005 The OpenLDAP Foundation. * All rights reserved. * - * Permission is granted to anyone to use this software for any purpose - * on any computer system, and to alter it and redistribute it, subject - * to the following restrictions: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. * - * 1. The author is not responsible for the consequences of use of this - * software, no matter how awful, even if they arise from flaws in it. - * - * 2. The origin of this software must not be misrepresented, either by - * explicit claim or by omission. Since few users ever read sources, - * credits should appear in the documentation. - * - * 3. Altered versions must be plainly marked as such, and must not be - * misrepresented as being the original software. Since few users - * ever read sources, credits should appear in the documentation. - * - * 4. This notice may not be removed or altered. - * - ******************************************************************************/ + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* ACKNOWLEDGEMENT: + * This work was initially developed by Pierangelo Masarati for + * inclusion in OpenLDAP Software. + */ #include @@ -44,7 +39,7 @@ rewrite_cookie_cmp( assert( s2 != NULL ); assert( s1->ls_cookie != NULL ); assert( s2->ls_cookie != NULL ); - + return ( ( s1->ls_cookie < s2->ls_cookie ) ? -1 : ( ( s1->ls_cookie > s2->ls_cookie ) ? 1 : 0 ) ); } @@ -68,6 +63,8 @@ rewrite_cookie_dup( assert( s1->ls_cookie != NULL ); assert( s2->ls_cookie != NULL ); + assert( s1->ls_cookie != s2->ls_cookie ); + return ( ( s1->ls_cookie == s2->ls_cookie ) ? -1 : 0 ); } @@ -80,24 +77,44 @@ rewrite_session_init( const void *cookie ) { - struct rewrite_session *session; - int rc; + struct rewrite_session *session, tmp; + int rc; assert( info != NULL ); assert( cookie != NULL ); - + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + tmp.ls_cookie = ( void * )cookie; + session = ( struct rewrite_session * )avl_find( info->li_cookies, + ( caddr_t )&tmp, rewrite_cookie_cmp ); + if ( session ) { + session->ls_count++; +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + return session; + } + session = calloc( sizeof( struct rewrite_session ), 1 ); if ( session == NULL ) { return NULL; } session->ls_cookie = ( void * )cookie; + session->ls_count = 1; #ifdef USE_REWRITE_LDAP_PVT_THREADS + if ( ldap_pvt_thread_mutex_init( &session->ls_mutex ) ) { + free( session ); + return NULL; + } if ( ldap_pvt_thread_rdwr_init( &session->ls_vars_mutex ) ) { + ldap_pvt_thread_mutex_destroy( &session->ls_mutex ); free( session ); return NULL; } - ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rc = avl_insert( &info->li_cookies, ( caddr_t )session, @@ -109,6 +126,11 @@ rewrite_session_init( #endif /* USE_REWRITE_LDAP_PVT_THREADS */ if ( rc != 0 ) { +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex ); + ldap_pvt_thread_mutex_destroy( &session->ls_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + free( session ); return NULL; } @@ -137,22 +159,38 @@ rewrite_session_find( session = ( struct rewrite_session * )avl_find( info->li_cookies, ( caddr_t )&tmp, rewrite_cookie_cmp ); #ifdef USE_REWRITE_LDAP_PVT_THREADS + if ( session ) { + ldap_pvt_thread_mutex_lock( &session->ls_mutex ); + } ldap_pvt_thread_rdwr_runlock( &info->li_cookies_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ return session; - +} + +/* + * Returns a session + */ +void +rewrite_session_return( + struct rewrite_info *info, + struct rewrite_session *session +) +{ + assert( session != NULL ); + ldap_pvt_thread_mutex_unlock( &session->ls_mutex ); } /* * Defines and inits a var with session scope */ int -rewrite_session_var_set( +rewrite_session_var_set_f( struct rewrite_info *info, const void *cookie, const char *name, - const char *value + const char *value, + int flags ) { struct rewrite_session *session; @@ -166,6 +204,13 @@ rewrite_session_var_set( session = rewrite_session_find( info, cookie ); if ( session == NULL ) { session = rewrite_session_init( info, cookie ); + if ( session == NULL ) { + return REWRITE_ERR; + } + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_lock( &session->ls_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ } #ifdef USE_REWRITE_LDAP_PVT_THREADS @@ -175,15 +220,16 @@ rewrite_session_var_set( var = rewrite_var_find( session->ls_vars, name ); if ( var != NULL ) { assert( var->lv_value.bv_val != NULL ); - free( var->lv_value.bv_val ); - var->lv_value.bv_val = strdup( value ); - var->lv_value.bv_len = strlen( value ); + + (void)rewrite_var_replace( var, value, flags ); + } else { - var = rewrite_var_insert( &session->ls_vars, name, value ); + var = rewrite_var_insert_f( &session->ls_vars, name, value, flags ); if ( var == NULL ) { #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ + rewrite_session_return( info, session ); return REWRITE_ERR; } } @@ -192,6 +238,8 @@ rewrite_session_var_set( ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ + rewrite_session_return( info, session ); + return REWRITE_SUCCESS; } @@ -236,7 +284,9 @@ rewrite_session_var_get( #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ - + + rewrite_session_return( info, session ); + return REWRITE_ERR; } else { value->bv_val = strdup( var->lv_value.bv_val ); @@ -246,10 +296,38 @@ rewrite_session_var_get( #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + rewrite_session_return( info, session ); return REWRITE_SUCCESS; } +static void +rewrite_session_clean( void *v_session ) +{ + struct rewrite_session *session = (struct rewrite_session *)v_session; + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + rewrite_var_delete( session->ls_vars ); + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex ); + ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex ); + ldap_pvt_thread_mutex_unlock( &session->ls_mutex ); + ldap_pvt_thread_mutex_destroy( &session->ls_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ +} + +static void +rewrite_session_free( void *v_session ) +{ + rewrite_session_clean( v_session ); + free( v_session ); +} + /* * Deletes a session */ @@ -259,25 +337,24 @@ rewrite_session_delete( const void *cookie ) { - struct rewrite_session *session, tmp; + struct rewrite_session *session, tmp = { 0 }; assert( info != NULL ); assert( cookie != NULL ); - tmp.ls_cookie = ( void * )cookie; - session = rewrite_session_find( info, cookie ); - if ( session != NULL ) { -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - rewrite_var_delete( session->ls_vars ); -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + if ( session == NULL ) { + return REWRITE_SUCCESS; } + if ( --session->ls_count > 0 ) { + rewrite_session_return( info, session ); + return REWRITE_SUCCESS; + } + + rewrite_session_clean( session ); + #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ @@ -288,7 +365,11 @@ rewrite_session_delete( /* * There is nothing to delete in the return value */ + tmp.ls_cookie = ( void * )cookie; avl_delete( &info->li_cookies, ( caddr_t )&tmp, rewrite_cookie_cmp ); + + free( session ); + #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ @@ -316,8 +397,14 @@ rewrite_session_destroy( * Should call per-session destruction routine ... */ - count = avl_free( info->li_cookies, NULL ); + count = avl_free( info->li_cookies, rewrite_session_free ); info->li_cookies = NULL; + +#if 0 + fprintf( stderr, "count = %d; num_cookies = %d\n", + count, info->li_num_cookies ); +#endif + assert( count == info->li_num_cookies ); info->li_num_cookies = 0;