From 6dfe0ec31ed5ac5c9868b08bd8340a2101e8b667 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Aug 2002 14:20:47 +0000 Subject: Sterling Hughes brings the share interface --- include/curl/curl.h | 46 +++++++++++++- lib/Makefile.am | 2 +- lib/share.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/share.h | 48 +++++++++++++++ lib/url.c | 16 +++++ lib/urldata.h | 3 +- 6 files changed, 279 insertions(+), 5 deletions(-) create mode 100644 lib/share.c create mode 100644 lib/share.h diff --git a/include/curl/curl.h b/include/curl/curl.h index 6c4722f60..7c7a47f9c 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -192,10 +192,11 @@ typedef enum { CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as default */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ CURLE_SEND_ERROR, /* 55 - failed sending network data */ CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ - + CURLE_SHARE_IN_USE, /* 57 - share is in use */ CURL_LAST /* never use! */ } CURLcode; @@ -562,9 +563,13 @@ typedef enum { /* Instruct libcurl to use a smaller receive buffer */ CINIT(BUFFERSIZE, LONG, 98), - /* Instruct libcurl to do not use any signal/alarm handlers, even with timeouts. */ + /* Instruct libcurl to never use any signal/alarm handlers, even with + timeouts. */ CINIT(NOSIGNAL, LONG, 99), + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + CURLOPT_LASTENTRY /* the last unusued */ } CURLoption; @@ -839,6 +844,41 @@ typedef enum { #define CURL_GLOBAL_NOTHING 0 #define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different types of locks that a share can aquire */ +typedef enum { + CURL_LOCK_TYPE_NONE = 0, + CURL_LOCK_TYPE_COOKIE = 1<<0, + CURL_LOCK_TYPE_DNS = 1<<1, + CURL_LOCK_TYPE_SSL_SESSION = 2<<1, + CURL_LOCK_TYPE_CONNECT = 2<<2, + CURL_LOCK_TYPE_LAST +} curl_lock_type; + +typedef void (*curl_lock_function)(CURL *, curl_lock_type, void *); +typedef void (*curl_unlock_function)(CURL *, curl_lock_type, void *); + +typedef struct { + unsigned int specifier; + unsigned int locked; + unsigned int dirty; + + curl_lock_function lockfunc; + curl_unlock_function unlockfunc; + void *clientdata; +} curl_share; + +curl_share *curl_share_init (void); +CURLcode curl_share_setopt (curl_share *, curl_lock_type, int); +CURLcode curl_share_set_lock_function (curl_share *, curl_lock_function); +CURLcode curl_share_set_unlock_function (curl_share *, curl_unlock_function); +CURLcode curl_share_set_lock_data (curl_share *, void *); +CURLcode curl_share_destroy (curl_share *); + #ifdef __cplusplus } #endif diff --git a/lib/Makefile.am b/lib/Makefile.am index 3efcdf2c2..2f03a8592 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -60,7 +60,7 @@ escape.h getpass.c netrc.c telnet.h \ getinfo.c getinfo.h transfer.c strequal.c strequal.h easy.c \ security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h \ http_chunks.c http_chunks.h strtok.c strtok.h connect.c connect.h \ -llist.c llist.h hash.c hash.h multi.c +llist.c llist.h hash.c hash.h multi.c share.c share.h noinst_HEADERS = setup.h transfer.h diff --git a/lib/share.c b/lib/share.c new file mode 100644 index 000000000..1050e50a1 --- /dev/null +++ b/lib/share.c @@ -0,0 +1,169 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. + * + * In order to be useful for every potential user, curl and libcurl are + * dual-licensed under the MPL and the MIT/X-derivate licenses. + * + * 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 MPL or the MIT/X-derivate + * licenses. You may pick one of these licenses. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id$ + *****************************************************************************/ + +#include "setup.h" +#include +#include +#include "share.h" +#include "urldata.h" + +/* The last #include file should be: */ +#ifdef MALLOCDEBUG +#include "memdebug.h" +#endif + +#define CURL_SHARE_SET_LOCKED(__share, __type) ((__share)->locked += (__type)) +#define CURL_SHARE_SET_UNLOCKED(__share, __type) ((__share)->locked -= (__type)) + +#define CURL_SHARE_SET_USED(__share, __type) ((__share)->specifier += (__type)) +#define CURL_SHARE_SET_UNUSED(__share, __type) ((__share)->specifier -= (__type)) +#define CURL_SHARE_IS_USED(__share, __type) ((__share)->specifier & (__type)) +#define CURL_SHARE_IS_LOCKED(__share, __type) ((__share)->locked & (__type)) + +#define CURL_SHARE_IS_DIRTY(__share) ((__share)->dirty) + +#define CURL_SHARE_GET(__handle) (((struct SessionHandle *) (__handle))->share) + +curl_share * +curl_share_init (void) +{ + curl_share *share = (curl_share *) malloc (sizeof (curl_share)); + if (share) { + memset (share, 0, sizeof (curl_share)); + } + + return share; +} + +CURLcode +curl_share_setopt (curl_share *share, curl_lock_type option, int enable) +{ + if (CURL_SHARE_IS_DIRTY(share)) { + return CURLE_SHARE_IN_USE; + } + + if (enable) { + CURL_SHARE_SET_USED (share, option); + } + else { + CURL_SHARE_SET_UNUSED (share, option); + } + + return CURLE_OK; +} + +CURLcode +curl_share_set_lock_function (curl_share *share, curl_lock_function lock) +{ + if (CURL_SHARE_IS_DIRTY(share)) { + return CURLE_SHARE_IN_USE; + } + + share->lockfunc = lock; + return CURLE_OK; +} + +CURLcode +curl_share_set_unlock_function (curl_share *share, curl_unlock_function unlock) +{ + if (CURL_SHARE_IS_DIRTY(share)) { + return CURLE_SHARE_IN_USE; + } + + share->unlockfunc = unlock; + return CURLE_OK; +} + +CURLcode +curl_share_set_lock_data (curl_share *share, void *data) +{ + if (CURL_SHARE_IS_DIRTY(share)) { + return CURLE_SHARE_IN_USE; + } + + share->clientdata = data; + return CURLE_OK; +} + +Curl_share_error +Curl_share_acquire_lock (CURL *handle, curl_lock_type type) +{ + curl_share *share = CURL_SHARE_GET (handle); + if (share == NULL) { + return SHARE_ERROR_INVALID; + } + + if (! (share->specifier & type)) { + return SHARE_ERROR_NOT_REGISTERED; + } + + if (CURL_SHARE_IS_LOCKED (share, type)) { + return SHARE_ERROR_OK; + } + + share->lockfunc (handle, type, share->clientdata); + CURL_SHARE_SET_LOCKED (share, type); + + return SHARE_ERROR_OK; +} + +Curl_share_error +Curl_share_release_lock (CURL *handle, curl_lock_type type) +{ + curl_share *share = CURL_SHARE_GET(handle); + if (share == NULL) { + return SHARE_ERROR_INVALID; + } + + if (! (share->specifier & type)) { + return SHARE_ERROR_NOT_REGISTERED; + } + + if (!CURL_SHARE_IS_LOCKED (share, type)) { + return SHARE_ERROR_OK; + } + + share->unlockfunc (handle, type, share->clientdata); + CURL_SHARE_SET_UNLOCKED (share, type); + + return SHARE_ERROR_OK; +} + +CURLcode curl_share_destroy (curl_share *share) +{ + if (CURL_SHARE_IS_DIRTY(share)) { + return CURLE_SHARE_IN_USE; + } + + free (share); + + return CURLE_OK; +} + +/* + * local variables: + * eval: (load-file "../curl-mode.el") + * end: + * vim600: fdm=marker + * vim: et sw=2 ts=2 sts=2 tw=78 + */ diff --git a/lib/share.h b/lib/share.h new file mode 100644 index 000000000..5550c6442 --- /dev/null +++ b/lib/share.h @@ -0,0 +1,48 @@ +#ifndef __CURL_SHARE_H +#define __CURL_SHARE_H + +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. + * + * In order to be useful for every potential user, curl and libcurl are + * dual-licensed under the MPL and the MIT/X-derivate licenses. + * + * 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 MPL or the MIT/X-derivate + * licenses. You may pick one of these licenses. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id$ + *****************************************************************************/ + +#include "setup.h" +#include + +typedef enum { + SHARE_ERROR_OK = 0, + SHARE_ERROR_INVALID, + SHARE_ERROR_NOT_REGISTERED, + SHARE_ERROR_LAST +} Curl_share_error; + +Curl_share_error Curl_share_aquire_lock (CURL *, curl_lock_type); +Curl_share_error Curl_share_release_lock (CURL *, curl_lock_type); + +#endif /* __CURL_SHARE_H */ + +/* + * local variables: + * eval: (load-file "../curl-mode.el") + * end: + * vim600: fdm=marker + * vim: et sw=2 ts=2 sts=2 tw=78 + */ diff --git a/lib/url.c b/lib/url.c index ead5eb494..08180efa9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -178,6 +178,10 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_SSL_Close_All(data); #endif + /* No longer a dirty share, if it exists */ + if (data->share) + data->share->dirty--; + if(data->state.auth_host) free(data->state.auth_host); @@ -1032,6 +1036,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.no_signal = va_arg(param, long) ? TRUE : FALSE; break; + case CURLOPT_SHARE: + { + curl_share *set; + set = va_arg(param, curl_share *); + if(data->share) + data->share->dirty--; + + data->share = set; + data->share->dirty++; + } + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ diff --git a/lib/urldata.h b/lib/urldata.h index 44a4a7200..dece629fd 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -694,7 +694,8 @@ struct UserDefined { * 'struct urlstate' instead. */ struct SessionHandle { - curl_hash *hostcache; + curl_hash *hostcache; + curl_share *share; /* Share, handles global variable mutexing */ struct UserDefined set; /* values set by the libcurl user */ struct DynamicStatic change; /* possibly modified userdefined data */ -- cgit v1.2.3