1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
9 * Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
10 *
11 * This software is licensed as described in the file COPYING, which
12 * you should have received as part of this distribution. The terms
13 * are also available at http://curl.haxx.se/docs/copyright.html.
14 *
15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 * copies of the Software, and permit persons to whom the Software is
17 * furnished to do so, under the terms of the COPYING file.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ***************************************************************************/
23
24#include "curl_setup.h"
25
26#include <curl/curl.h>
27
28#include "urldata.h"
29#include "url.h"
30#include "progress.h"
31#include "multiif.h"
32#include "bundles.h"
33#include "sendf.h"
34#include "rawstr.h"
35
36#include "curl_memory.h"
37/* The last #include file should be: */
38#include "memdebug.h"
39
40static void conn_llist_dtor(void *user, void *element)
41{
42  struct connectdata *data = element;
43  (void)user;
44
45  data->bundle = NULL;
46}
47
48CURLcode Curl_bundle_create(struct SessionHandle *data,
49                            struct connectbundle **cb_ptr)
50{
51  (void)data;
52  DEBUGASSERT(*cb_ptr == NULL);
53  *cb_ptr = malloc(sizeof(struct connectbundle));
54  if(!*cb_ptr)
55    return CURLE_OUT_OF_MEMORY;
56
57  (*cb_ptr)->num_connections = 0;
58  (*cb_ptr)->server_supports_pipelining = FALSE;
59
60  (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
61  if(!(*cb_ptr)->conn_list) {
62    Curl_safefree(*cb_ptr);
63    return CURLE_OUT_OF_MEMORY;
64  }
65  return CURLE_OK;
66}
67
68void Curl_bundle_destroy(struct connectbundle *cb_ptr)
69{
70  if(!cb_ptr)
71    return;
72
73  if(cb_ptr->conn_list) {
74    Curl_llist_destroy(cb_ptr->conn_list, NULL);
75    cb_ptr->conn_list = NULL;
76  }
77  Curl_safefree(cb_ptr);
78}
79
80/* Add a connection to a bundle */
81CURLcode Curl_bundle_add_conn(struct connectbundle *cb_ptr,
82                              struct connectdata *conn)
83{
84  if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
85    return CURLE_OUT_OF_MEMORY;
86
87  conn->bundle = cb_ptr;
88
89  cb_ptr->num_connections++;
90  return CURLE_OK;
91}
92
93/* Remove a connection from a bundle */
94int Curl_bundle_remove_conn(struct connectbundle *cb_ptr,
95                            struct connectdata *conn)
96{
97  struct curl_llist_element *curr;
98
99  curr = cb_ptr->conn_list->head;
100  while(curr) {
101    if(curr->ptr == conn) {
102      Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
103      cb_ptr->num_connections--;
104      conn->bundle = NULL;
105      return 1; /* we removed a handle */
106    }
107    curr = curr->next;
108  }
109  return 0;
110}
111