18
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
* KIND, either express or implied.
21
* $Id: multi.c,v 1.138 2007-04-10 20:46:40 bagder Exp $
21
* $Id: multi.c,v 1.148 2007-06-26 21:09:28 bagder Exp $
22
22
***************************************************************************/
50
50
/* The last #include file should be: */
51
51
#include "memdebug.h"
54
CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
55
to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every
56
CURL handle takes 45-50 K memory, therefore this 3K are not significant.
58
#ifndef CURL_SOCKET_HASH_TABLE_SIZE
59
#define CURL_SOCKET_HASH_TABLE_SIZE 911
53
62
struct Curl_message {
54
63
/* the 'CURLMsg' is the part that is visible to the external user */
55
64
struct CURLMsg extmsg;
121
130
#define CURL_MULTI_HANDLE 0x000bab1e
123
132
#define GOOD_MULTI_HANDLE(x) \
124
((x)&&(((struct Curl_multi *)x)->type == CURL_MULTI_HANDLE))
133
((x)&&(((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
125
134
#define GOOD_EASY_HANDLE(x) \
126
(((struct SessionHandle *)x)->magic == CURLEASY_MAGIC_NUMBER)
135
(((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER)
128
137
/* This is the struct known as CURLM on the outside */
129
138
struct Curl_multi {
161
170
/* shared connection cache */
162
171
struct conncache *connc;
172
long maxconnects; /* if >0, a fixed limit of the maximum number of entries
173
we're allowed to grow the connection cache to */
164
175
/* list of easy handles kept around for doing nice connection closures */
165
176
struct closure *closure;
317
static size_t fd_key_compare(void*k1, size_t k1_len, void*k2, size_t k2_len)
319
(void) k1_len; (void) k2_len;
321
return ((*((int* ) k1)) == (*((int* ) k2))) ? 1 : 0;
324
static size_t hash_fd(void* key, size_t key_length, size_t slots_num)
326
int fd = * ((int* ) key);
329
return (fd % (int)slots_num);
307
333
* sh_init() creates a new socket hash and returns the handle for it.
324
350
static struct curl_hash *sh_init(void)
326
return Curl_hash_alloc(97, sh_freeentry);
352
return Curl_hash_alloc(CURL_SOCKET_HASH_TABLE_SIZE, hash_fd, fd_key_compare,
329
356
CURLM *curl_multi_init(void)
469
496
/* make the SessionHandle struct refer back to this struct */
470
497
easy->easy_handle->set.one_easy = easy;
499
/* Set the timeout for this handle to expire really soon so that it will
500
be taken care of even when this handle is added in the midst of operation
501
when only the curl_multi_socket() API is used. During that flow, only
502
sockets that time-out or have actions will be dealt with. Since this
503
handle has no action yet, we make sure it times out to get things to
505
Curl_expire(easy->easy_handle, 10);
472
507
/* increase the node-counter */
473
508
multi->num_easy++;
476
511
/* We want the connection cache to have plenty room. Before we supported
477
512
the shared cache every single easy handle had 5 entries in their cache
479
CURLcode res = Curl_ch_connc(easy_handle, multi->connc,
480
multi->connc->num*4);
482
/* TODO: we need to do some cleaning up here! */
483
return CURLM_OUT_OF_MEMORY;
514
int newmax = multi->num_easy * 4;
516
if(multi->maxconnects && (multi->maxconnects < newmax))
517
/* don't grow beyond the allowed size */
518
newmax = multi->maxconnects;
520
if(newmax > multi->connc->num) {
521
/* we only do this is we can in fact grow the cache */
522
CURLcode res = Curl_ch_connc(easy_handle, multi->connc, newmax);
524
/* TODO: we need to do some cleaning up here! */
525
return CURLM_OUT_OF_MEMORY;
486
529
/* increase the alive-counter */
889
932
if(CURLE_OK == easy->result) {
890
933
/* Add this handle to the send pipeline */
891
Curl_addHandleToPipeline(easy->easy_handle,
892
easy->easy_conn->send_pipe);
895
/* We're now waiting for an asynchronous name lookup */
896
multistate(easy, CURLM_STATE_WAITRESOLVE);
898
/* after the connect has been sent off, go WAITCONNECT unless the
899
protocol connect is already done and we can go directly to
901
result = CURLM_CALL_MULTI_PERFORM;
904
multistate(easy, CURLM_STATE_WAITDO);
934
easy->result = Curl_addHandleToPipeline(easy->easy_handle,
935
easy->easy_conn->send_pipe);
936
if(CURLE_OK == easy->result) {
938
/* We're now waiting for an asynchronous name lookup */
939
multistate(easy, CURLM_STATE_WAITRESOLVE);
941
/* after the connect has been sent off, go WAITCONNECT unless the
942
protocol connect is already done and we can go directly to
944
result = CURLM_CALL_MULTI_PERFORM;
947
multistate(easy, CURLM_STATE_WAITDO);
906
949
#ifndef CURL_DISABLE_HTTP
907
if (easy->easy_conn->bits.tunnel_connecting)
908
multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
950
if (easy->easy_conn->bits.tunnel_connecting)
951
multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
911
multistate(easy, CURLM_STATE_WAITCONNECT);
954
multistate(easy, CURLM_STATE_WAITCONNECT);
988
1032
if(!protocol_connect) {
989
1033
/* We have a TCP connection, but 'protocol_connect' may be false
990
1034
and then we continue to 'STATE_PROTOCONNECT'. If protocol
991
connect is TRUE, we move on to STATE_DO. */
992
multistate(easy, CURLM_STATE_PROTOCONNECT);
1035
connect is TRUE, we move on to STATE_DO.
1036
BUT if we are using a proxy we must change to WAITPROXYCONNECT
1038
#ifndef CURL_DISABLE_HTTP
1039
if (easy->easy_conn->bits.tunnel_connecting)
1040
multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
1043
multistate(easy, CURLM_STATE_PROTOCONNECT);
995
1046
/* after the connect has completed, go WAITDO */
1145
1196
Curl_removeHandleFromPipeline(easy->easy_handle,
1146
1197
easy->easy_conn->send_pipe);
1147
1198
/* Add ourselves to the recv pipeline */
1148
Curl_addHandleToPipeline(easy->easy_handle,
1149
easy->easy_conn->recv_pipe);
1199
easy->result = Curl_addHandleToPipeline(easy->easy_handle,
1200
easy->easy_conn->recv_pipe);
1150
1201
multistate(easy, CURLM_STATE_WAITPERFORM);
1151
1202
result = CURLM_CALL_MULTI_PERFORM;
1385
1436
multi->num_msgs++; /* increase message counter */
1439
if(CURLM_CALL_MULTI_PERFORM == result)
1440
/* Set the timeout for this handle to expire really soon so that it will
1441
be taken care of even when this handle is added in the midst of
1442
operation when only the curl_multi_socket() API is used. During that
1443
flow, only sockets that time-out or have actions will be dealt
1444
with. Since this handle has no action yet, we make sure it times out to
1445
get things to happen. Also, this makes it less important for callers of
1446
the curl_multi_* functions to bother about the CURLM_CALL_MULTI_PERFORM
1447
return code, as long as they deal with the timeouts properly. */
1448
Curl_expire(easy->easy_handle, 10);
1698
1761
/* bad bad bad bad bad bad bad */
1699
1762
return CURLM_INTERNAL_ERROR;
1764
if (data->set.one_easy->easy_conn) /* set socket event bitmask */
1765
data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
1701
1767
result = multi_runsingle(multi, data->set.one_easy);
1703
if(result == CURLM_OK)
1769
if (data->set.one_easy->easy_conn)
1770
data->set.one_easy->easy_conn->cselect_bits = 0;
1772
if(CURLM_OK >= result)
1704
1773
/* get the socket(s) and check if the state has been changed since
1706
1775
singlesocket(multi, data->set.one_easy);
1783
1852
case CURLMOPT_TIMERDATA:
1784
1853
multi->timer_userp = va_arg(param, void *);
1855
case CURLMOPT_MAXCONNECTS:
1856
multi->maxconnects = va_arg(param, long);
1787
1859
res = CURLM_UNKNOWN_OPTION;
1866
/* we define curl_multi_socket() in the public multi.h header */
1867
#undef curl_multi_socket
1795
1869
CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
1796
1870
int *running_handles)
1798
1872
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
1800
if (CURLM_OK == result)
1873
0, running_handles);
1874
if (CURLM_OK >= result)
1875
update_timer((struct Curl_multi *)multi_handle);
1879
CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s,
1880
int ev_bitmask, int *running_handles)
1882
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
1883
ev_bitmask, running_handles);
1884
if (CURLM_OK >= result)
1801
1885
update_timer((struct Curl_multi *)multi_handle);
1808
1892
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
1809
TRUE, CURL_SOCKET_BAD, running_handles);
1810
if (CURLM_OK == result)
1893
TRUE, CURL_SOCKET_BAD, 0, running_handles);
1894
if (CURLM_OK >= result)
1811
1895
update_timer((struct Curl_multi *)multi_handle);