Sterling Hughes brings the share interface

This commit is contained in:
Daniel Stenberg 2002-08-13 14:20:47 +00:00
parent 8b3f1cebda
commit 6dfe0ec31e
6 changed files with 279 additions and 5 deletions

View File

@ -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

View File

@ -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

169
lib/share.c Normal file
View File

@ -0,0 +1,169 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, 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 <stdlib.h>
#include <curl/curl.h>
#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
*/

48
lib/share.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef __CURL_SHARE_H
#define __CURL_SHARE_H
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, 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 <curl/curl.h>
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
*/

View File

@ -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 */

View File

@ -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 */