/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * $Id: share.c,v 1.16 2004/02/26 11:39:38 bagder Exp $ ***************************************************************************/ #include "setup.h" #include #include #include #include #include "urldata.h" #include "share.h" /* The last #include file should be: */ #ifdef CURLDEBUG #include "memdebug.h" #endif CURLSH * curl_share_init(void) { struct Curl_share *share = (struct Curl_share *)malloc(sizeof(struct Curl_share)); if (share) { memset (share, 0, sizeof(struct Curl_share)); share->specifier |= (1<dirty) /* don't allow setting options while one or more handles are already using this share */ return CURLSHE_IN_USE; va_start(param, option); switch(option) { case CURLSHOPT_SHARE: /* this is a type this share will share */ type = va_arg(param, int); share->specifier |= (1<hostcache) { share->hostcache = Curl_hash_alloc(7, Curl_freednsinfo); } break; case CURL_LOCK_DATA_COOKIE: if (!share->cookies) { share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE ); } break; case CURL_LOCK_DATA_SSL_SESSION: break; case CURL_LOCK_DATA_CONNECT: break; default: return CURLSHE_BAD_OPTION; } break; case CURLSHOPT_UNSHARE: /* this is a type this share will no longer share */ type = va_arg(param, int); share->specifier &= ~(1<hostcache) { Curl_hash_destroy(share->hostcache); share->hostcache = NULL; } break; case CURL_LOCK_DATA_COOKIE: if (share->cookies) { Curl_cookie_cleanup(share->cookies); share->cookies = NULL; } break; case CURL_LOCK_DATA_SSL_SESSION: break; case CURL_LOCK_DATA_CONNECT: break; default: return CURLSHE_BAD_OPTION; } break; case CURLSHOPT_LOCKFUNC: lockfunc = va_arg(param, curl_lock_function); share->lockfunc = lockfunc; break; case CURLSHOPT_UNLOCKFUNC: unlockfunc = va_arg(param, curl_unlock_function); share->unlockfunc = unlockfunc; break; case CURLSHOPT_USERDATA: ptr = va_arg(param, void *); share->clientdata = ptr; break; default: return CURLSHE_BAD_OPTION; } return CURLSHE_OK; } CURLSHcode curl_share_cleanup(CURLSH *sh) { struct Curl_share *share = (struct Curl_share *)sh; if (share == NULL) return CURLSHE_INVALID; share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE, share->clientdata); if (share->dirty) { share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); return CURLSHE_IN_USE; } if(share->hostcache) Curl_hash_destroy(share->hostcache); if(share->cookies) Curl_cookie_cleanup(share->cookies); share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); free (share); return CURLSHE_OK; } CURLSHcode Curl_share_lock(struct SessionHandle *data, curl_lock_data type, curl_lock_access accesstype) { struct Curl_share *share = data->share; if (share == NULL) return CURLSHE_INVALID; if(share->specifier & (1<lockfunc) /* only call this if set! */ share->lockfunc(data, type, accesstype, share->clientdata); } /* else if we don't share this, pretend successful lock */ return CURLSHE_OK; } CURLSHcode Curl_share_unlock(struct SessionHandle *data, curl_lock_data type) { struct Curl_share *share = data->share; if (share == NULL) return CURLSHE_INVALID; if(share->specifier & (1<unlockfunc) /* only call this if set! */ share->unlockfunc (data, type, share->clientdata); } return CURLSHE_OK; }