Sterling Hughes brings the share interface
This commit is contained in:
parent
8b3f1cebda
commit
6dfe0ec31e
@ -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
|
||||
|
@ -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
169
lib/share.c
Normal 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
48
lib/share.h
Normal 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
|
||||
*/
|
16
lib/url.c
16
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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user