~ubuntu-branches/ubuntu/natty/curl/natty-proposed

« back to all changes in this revision

Viewing changes to lib/multi.c

  • Committer: Bazaar Package Importer
  • Author(s): Ramakrishnan Muthukrishnan
  • Date: 2010-08-12 08:20:48 UTC
  • mto: (3.4.8 sid)
  • mto: This revision was merged to the branch mainline in revision 43.
  • Revision ID: james.westby@ubuntu.com-20100812082048-7g7fewx1ai2ozgsf
Tags: upstream-7.21.1
ImportĀ upstreamĀ versionĀ 7.21.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
struct Curl_message {
62
62
  /* the 'CURLMsg' is the part that is visible to the external user */
63
63
  struct CURLMsg extmsg;
64
 
  struct Curl_message *next;
65
64
};
66
65
 
67
66
/* NOTE: if you add a state here, add the name to the statename[] array as
110
109
  CURLMstate state;  /* the handle's state */
111
110
  CURLcode result;   /* previous result */
112
111
 
113
 
  struct Curl_message *msg; /* A pointer to one single posted message.
114
 
                               Cleanup should be done on this pointer NOT on
115
 
                               the linked list in Curl_multi.  This message
116
 
                               will be deleted when this handle is removed
117
 
                               from the multi-handle */
118
 
  int msg_num; /* number of messages left in 'msg' to return */
 
112
  struct Curl_message msg; /* A single posted message. */
 
113
  int msg_stored; /* a message is stored in 'msg' to return */
119
114
 
120
115
  /* Array with the plain socket numbers this handle takes care of, in no
121
116
     particular order. Note that all sockets are added to the sockhash, where
656
651
         to that since we're not part of that handle anymore */
657
652
      easy->easy_handle->state.connc = NULL;
658
653
 
 
654
      /* Since we return the connection back to the communal connection pool
 
655
         we mark the last connection as inaccessible */
 
656
      easy->easy_handle->state.lastconnect = -1;
 
657
 
659
658
      /* Modify the connectindex since this handle can't point to the
660
659
         connection cache anymore.
661
660
 
693
692
 
694
693
    /* NOTE NOTE NOTE
695
694
       We do not touch the easy handle here! */
696
 
    if(easy->msg)
697
 
      free(easy->msg);
698
695
    free(easy);
699
696
 
700
697
    multi->num_easy--; /* one less to care about now */
1307
1304
 
1308
1305
    case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
1309
1306
      /* if both rates are within spec, resume transfer */
1310
 
      Curl_pgrsUpdate(easy->easy_conn);
1311
1307
      if( ( ( easy->easy_handle->set.max_send_speed == 0 ) ||
1312
1308
            ( easy->easy_handle->progress.ulspeed <
1313
1309
              easy->easy_handle->set.max_send_speed ) )  &&
1528
1524
 
1529
1525
        multistate(easy, CURLM_STATE_COMPLETED);
1530
1526
      }
 
1527
      /* if there's still a connection to use, call the progress function */
 
1528
      else if(easy->easy_conn && Curl_pgrsUpdate(easy->easy_conn))
 
1529
        easy->result = CURLE_ABORTED_BY_CALLBACK;
1531
1530
    }
1532
1531
  } while(0);
1533
 
  if((CURLM_STATE_COMPLETED == easy->state) && !easy->msg) {
 
1532
  if((CURLM_STATE_COMPLETED == easy->state) && !easy->msg_stored) {
1534
1533
    if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
1535
1534
      /* clear out the usage of the shared DNS cache */
1536
1535
      easy->easy_handle->dns.hostcache = NULL;
1537
1536
      easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
1538
1537
    }
1539
1538
 
1540
 
    /* now add a node to the Curl_message linked list with this info */
1541
 
    msg = malloc(sizeof(struct Curl_message));
1542
 
 
1543
 
    if(!msg)
1544
 
      return CURLM_OUT_OF_MEMORY;
 
1539
    /* now fill in the Curl_message with this info */
 
1540
    msg = &easy->msg;
1545
1541
 
1546
1542
    msg->extmsg.msg = CURLMSG_DONE;
1547
1543
    msg->extmsg.easy_handle = easy->easy_handle;
1548
1544
    msg->extmsg.data.result = easy->result;
1549
 
    msg->next = NULL;
1550
1545
 
1551
 
    easy->msg = msg;
1552
 
    easy->msg_num = 1; /* there is one unread message here */
 
1546
    easy->msg_stored = 1; /* there is an unread message here */
1553
1547
 
1554
1548
    multi->num_msgs++; /* increase message counter */
1555
1549
  }
1564
1558
  struct Curl_one_easy *easy;
1565
1559
  CURLMcode returncode=CURLM_OK;
1566
1560
  struct Curl_tree *t;
 
1561
  struct timeval now = Curl_tvnow();
1567
1562
 
1568
1563
  if(!GOOD_MULTI_HANDLE(multi))
1569
1564
    return CURLM_BAD_HANDLE;
1601
1596
   * Simply remove all expired timers from the splay since handles are dealt
1602
1597
   * with unconditionally by this function and curl_multi_timeout() requires
1603
1598
   * that already passed/handled expire times are removed from the splay.
 
1599
   *
 
1600
   * It is important that the 'now' value is set at the entry of this function
 
1601
   * and not for the current time as it may have ticked a little while since
 
1602
   * then and then we risk this loop to remove timers that actually have not
 
1603
   * been handled!
1604
1604
   */
1605
1605
  do {
1606
 
    struct timeval now = Curl_tvnow();
1607
 
 
1608
1606
    multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
1609
1607
    if(t) {
1610
1608
      struct SessionHandle *d = t->payload;
1689
1687
 
1690
1688
      Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association */
1691
1689
 
1692
 
      if(easy->msg)
1693
 
        free(easy->msg);
1694
1690
      free(easy);
1695
1691
      easy = nexteasy;
1696
1692
    }
1717
1713
 
1718
1714
    easy=multi->easy.next;
1719
1715
    while(easy != &multi->easy) {
1720
 
      if(easy->msg_num) {
1721
 
        easy->msg_num--;
 
1716
      if(easy->msg_stored) {
 
1717
        easy->msg_stored = 0;
1722
1718
        break;
1723
1719
      }
1724
1720
      easy = easy->next;
1729
1725
    multi->num_msgs--;
1730
1726
    *msgs_in_queue = multi->num_msgs;
1731
1727
 
1732
 
    return &easy->msg->extmsg;
 
1728
    return &easy->msg.extmsg;
1733
1729
  }
1734
1730
  else
1735
1731
    return NULL;
2168
2164
                                              struct connectdata *conn)
2169
2165
{
2170
2166
  size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
 
2167
  struct curl_llist_element *sendhead = conn->send_pipe->head;
2171
2168
  struct curl_llist *pipeline;
 
2169
  CURLcode rc;
2172
2170
 
2173
2171
  if(!Curl_isPipeliningEnabled(handle) ||
2174
2172
     pipeLen == 0)
2181
2179
      pipeline = conn->pend_pipe;
2182
2180
  }
2183
2181
 
2184
 
  return Curl_addHandleToPipeline(handle, pipeline);
 
2182
  rc = Curl_addHandleToPipeline(handle, pipeline);
 
2183
 
 
2184
  if (pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
 
2185
      /* this is a new one as head, expire it */
 
2186
      conn->writechannel_inuse = FALSE; /* not in use yet */
 
2187
      infof(conn->data, "%p is at send pipe head!\n",
 
2188
            conn->send_pipe->head->ptr);
 
2189
      Curl_expire(conn->send_pipe->head->ptr, 1);
 
2190
  }
 
2191
 
 
2192
  return rc;
2185
2193
}
2186
2194
 
2187
2195
static int checkPendPipeline(struct connectdata *conn)