mirror of
https://github.com/curl/curl.git
synced 2024-12-15 06:40:09 +08:00
de05bcb706
Multi handles repeatedly invert the queue of pending easy handles when used with CURLMOPT_MAX_TOTAL_CONNECTIONS. This is caused by a multistep process involving Curl_splaygetbest and violates the FIFO property of the multi handle. This patch fixes this issue by redefining the "best" node in the context of timeouts as the "smallest not larger than now", and implementing the necessary data structure modifications to do this effectively, namely: - splay nodes with the same key are now stored in a doubly-linked circular list instead of a non-circular one to enable O(1) insertion to the tail of the list - Curl_splayinsert inserts nodes with the same key to the tail of the same list - in case of multiple nodes with the same key, the one on the head of the list gets selected
68 lines
2.7 KiB
C
68 lines
2.7 KiB
C
#ifndef HEADER_CURL_SPLAY_H
|
|
#define HEADER_CURL_SPLAY_H
|
|
/***************************************************************************
|
|
* _ _ ____ _
|
|
* Project ___| | | | _ \| |
|
|
* / __| | | | |_) | |
|
|
* | (__| |_| | _ <| |___
|
|
* \___|\___/|_| \_\_____|
|
|
*
|
|
* Copyright (C) 1997 - 2016, Daniel Stenberg, <daniel@haxx.se>, 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 https://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.
|
|
*
|
|
***************************************************************************/
|
|
#include "curl_setup.h"
|
|
|
|
struct Curl_tree {
|
|
struct Curl_tree *smaller; /* smaller node */
|
|
struct Curl_tree *larger; /* larger node */
|
|
struct Curl_tree *samen; /* points to the next node with identical key */
|
|
struct Curl_tree *samep; /* points to the prev node with identical key */
|
|
struct timeval key; /* this node's "sort" key */
|
|
void *payload; /* data the splay code doesn't care about */
|
|
};
|
|
|
|
struct Curl_tree *Curl_splay(struct timeval i,
|
|
struct Curl_tree *t);
|
|
|
|
struct Curl_tree *Curl_splayinsert(struct timeval key,
|
|
struct Curl_tree *t,
|
|
struct Curl_tree *newnode);
|
|
|
|
#if 0
|
|
struct Curl_tree *Curl_splayremove(struct timeval key,
|
|
struct Curl_tree *t,
|
|
struct Curl_tree **removed);
|
|
#endif
|
|
|
|
struct Curl_tree *Curl_splaygetbest(struct timeval key,
|
|
struct Curl_tree *t,
|
|
struct Curl_tree **removed);
|
|
|
|
int Curl_splayremovebyaddr(struct Curl_tree *t,
|
|
struct Curl_tree *removenode,
|
|
struct Curl_tree **newroot);
|
|
|
|
#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec) < (j.tv_sec)) ? -1 : \
|
|
( ((i.tv_sec) > (j.tv_sec)) ? 1 : \
|
|
( ((i.tv_usec) < (j.tv_usec)) ? -1 : \
|
|
( ((i.tv_usec) > (j.tv_usec)) ? 1 : 0))))
|
|
|
|
#ifdef DEBUGBUILD
|
|
void Curl_splayprint(struct Curl_tree * t, int d, char output);
|
|
#else
|
|
#define Curl_splayprint(x,y,z) Curl_nop_stmt
|
|
#endif
|
|
|
|
#endif /* HEADER_CURL_SPLAY_H */
|