Ejemplo n.º 1
1
	bool	CMultiHttp::Perform()
	{
		struct timeval timeout;
		int still_running=0;
		int rc=0;			/* select() return code */ 
		CURLMcode mc;		/* curl_multi_fdset() return code */ 
		fd_set fdread;
		fd_set fdwrite;
		fd_set fdexcep;
		int maxfd = -1;
		long curl_timeo = -1;
		FD_ZERO(&fdread);
		FD_ZERO(&fdwrite);
		FD_ZERO(&fdexcep);
		/* set a suitable timeout to play around with */ 
		timeout.tv_sec = 5;
		timeout.tv_usec = 0;
		curl_multi_timeout(m_murl, &curl_timeo);
		if( curl_timeo==0 )
			curl_timeo=50;
		if(curl_timeo >= 0)
		{
			timeout.tv_sec = curl_timeo/1000;
			if(timeout.tv_sec > 1)
				timeout.tv_sec = 1;
			else
				timeout.tv_usec = (curl_timeo % 1000) * 1000;
		}
		/* get file descriptors from the transfers */ 
		mc = curl_multi_fdset(m_murl, &fdread, &fdwrite, &fdexcep, &maxfd);
		if(mc != CURLM_OK)
		{
			LOG_FUNC_P1(_T("curl_multi_fdset() failed, code %d"),mc);
			return false;
		}
		/* On success the value of maxfd is guaranteed to be >= -1. We call
         select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
         no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
         to sleep 100ms, which is the minimum suggested value in the
         curl_multi_fdset() doc. */
		if(maxfd == -1)
		{
			Sleep(100);
			rc = 0;
		}
		else
		{
			FD_SET(m_fds[1],&fdread);
			FD_SET(m_fds[1],&fdwrite);
			FD_SET(m_fds[1],&fdexcep);
			rc = ::select(maxfd+2, &fdread,&fdwrite, &fdexcep, &timeout);
			if(FD_ISSET(m_fds[1],&fdread))
			{
				std::string cmd;
				if( !recvcmd(m_fds[1],cmd) )
				{
					m_state = CMultiHttp::Terminate;
					return false;
				}
				if( cmd==CMD_CANCEL )
				{
					LOG_FUNC_P0(_T("url 后台线程 收到退出指令"));
					m_state = CMultiHttp::Terminate;
					return false;
				}
			}
		}
		switch(rc)
		{
		case -1:
			/* select error */ 
			break;
		case 0:
		default:
			while( CURLM_CALL_MULTI_PERFORM==curl_multi_perform(m_murl,&still_running) )
				;
			{
				struct CURLMsg *m;
				int msgQ=0;
				m = curl_multi_info_read(m_murl,&msgQ);
				if(m && (m->msg == CURLMSG_DONE))
				{
					CURL *e = m->easy_handle;
					if( !OneComplete(e,m->data.result) )
						still_running=0;
				}
			}
			break;
		}
		if( still_running )
			return true;
		m_state = CMultiHttp::Terminate;
		return false;
	}
Ejemplo n.º 2
0
bool
Net::Session::Select(int timeout_ms)
{
  fd_set rfds, wfds, efds;
  FD_ZERO(&rfds);
  FD_ZERO(&wfds);
  FD_ZERO(&efds);

  int max_fd;
  CURLMcode mcode = curl_multi_fdset(multi, &rfds, &wfds,
                                     &efds, &max_fd);
  if (mcode != CURLM_OK)
    return false;

  long curl_timeout;
  mcode = curl_multi_timeout(multi, &curl_timeout);
  if (mcode == CURLM_OK && curl_timeout >= 0) {
    if (curl_timeout < 50)
      curl_timeout = 50;

    if (timeout_ms < 0 || curl_timeout < (long)timeout_ms)
      timeout_ms = curl_timeout;
  }

  struct timeval timeout, *timeout_p;
  if (timeout_ms >= 0) {
    timeout.tv_sec = timeout_ms / 1000;
    timeout.tv_usec = timeout_ms * 1000;
    timeout_p = &timeout;
  } else
    timeout_p = NULL;

  int ret = select(max_fd, &rfds, &wfds, &efds, timeout_p);
  return ret > 0;
}
Ejemplo n.º 3
0
/* Called before all the file descriptors are polled by the glib main loop.
   We must have a look at all fds that libcurl wants polled. If any of them
   are new/no longer needed, we have to (de)register them with glib. */
gboolean prepare(GSource* source, gint* timeout) {
  D((stderr, "prepare\n"));
  assert(source == &curlSrc->source);

  if (curlSrc->multiHandle == 0) return FALSE;

  registerUnregisterFds();

  // Handle has been added. we are ready
  if (curlSrc->callPerform == -1) {
      s_currTimeout = *timeout = 0;
      return TRUE;
  }

  long curlTimeout = 0;
  curl_multi_timeout(curlSrc->multiHandle, &curlTimeout);

  // Curl tells us it is ready
  if (curlTimeout == 0) {
      s_currTimeout = *timeout = 0;
      return TRUE;
  }

  // Curl says wait forever. do it only when if we don't have pending
  // connections
  if (curlTimeout < 0) {
      s_currTimeout = *timeout = (s_numEasyHandles > 0) ? GLIBCURL_TIMEOUT : -1;
      return FALSE;
  }

  s_currTimeout = *timeout = MIN(GLIBCURL_TIMEOUT, curlTimeout);
  return FALSE;
}
/**
 * Function setting up file descriptors and scheduling task to run
 *
 * @param  plugin plugin as closure
 * @param now schedule task in 1ms, regardless of what curl may say
 * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok
 */
static int
client_schedule (struct Plugin *plugin, int now)
{
  fd_set rs;
  fd_set ws;
  fd_set es;
  int max;
  struct GNUNET_NETWORK_FDSet *grs;
  struct GNUNET_NETWORK_FDSet *gws;
  long to;
  CURLMcode mret;
  struct GNUNET_TIME_Relative timeout;

  /* Cancel previous scheduled task */
  if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK)
  {
    GNUNET_SCHEDULER_cancel (plugin->client_perform_task);
    plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK;
  }
  max = -1;
  FD_ZERO (&rs);
  FD_ZERO (&ws);
  FD_ZERO (&es);
  mret = curl_multi_fdset (plugin->client_mh, &rs, &ws, &es, &max);
  if (mret != CURLM_OK)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
                "curl_multi_fdset", __FILE__, __LINE__,
                curl_multi_strerror (mret));
    return GNUNET_SYSERR;
  }
  mret = curl_multi_timeout (plugin->client_mh, &to);
  if (to == -1)
    timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1);
  else
    timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to);
  if (now == GNUNET_YES)
    timeout = GNUNET_TIME_UNIT_MILLISECONDS;

  if (mret != CURLM_OK)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
                "curl_multi_timeout", __FILE__, __LINE__,
                curl_multi_strerror (mret));
    return GNUNET_SYSERR;
  }

  grs = GNUNET_NETWORK_fdset_create ();
  gws = GNUNET_NETWORK_fdset_create ();
  GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
  GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);

  plugin->client_perform_task =
      GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
                                   timeout, grs, gws,
                                   &client_run, plugin);
  GNUNET_NETWORK_fdset_destroy (gws);
  GNUNET_NETWORK_fdset_destroy (grs);
  return GNUNET_OK;
}
Ejemplo n.º 5
0
static void do_select_job(CURLM* cmh)
{
	fd_set fdread;
	fd_set fdwrite;
	fd_set fdexcep;
	int maxfd = -1;
	long curl_timeo = -1;

	FD_ZERO(&fdread);
	FD_ZERO(&fdwrite);
	FD_ZERO(&fdexcep);

	struct timeval timeout;
	timeout.tv_sec = 1;
	timeout.tv_usec = 0;

	curl_multi_timeout(cmh, &curl_timeo);
	if (curl_timeo >= 0)
	{
		timeout.tv_sec = curl_timeo / 1000;
		if (timeout.tv_sec > 1)
		{
			timeout.tv_sec = 1;
		}
		else
		{
			timeout.tv_usec = (curl_timeo % 1000) * 1000;
		}
	}

	curl_multi_fdset(cmh, &fdread, &fdwrite, &fdexcep, &maxfd);

	select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
}
Ejemplo n.º 6
0
smcp_status_t
smcp_curl_proxy_node_update_fdset(
    smcp_curl_proxy_node_t self,
    fd_set *read_fd_set,
    fd_set *write_fd_set,
    fd_set *error_fd_set,
    int *max_fd,
    cms_t *timeout
) {
    int fd = *max_fd;
    long cms_timeout = *timeout;

    curl_multi_fdset(
        self->curl_multi_handle,
        read_fd_set,
        write_fd_set,
        error_fd_set,
        &fd
    );

    *max_fd = MAX(*max_fd,fd);

    curl_multi_timeout(
        self->curl_multi_handle,
        &cms_timeout
    );

    if(cms_timeout!=-1) {
        *timeout = MIN(*timeout,cms_timeout);
    }

    return SMCP_STATUS_OK;
}
Ejemplo n.º 7
0
/**
 * The GSource prepare() method implementation.
 */
static gboolean
curl_source_prepare(G_GNUC_UNUSED GSource *source, G_GNUC_UNUSED gint *timeout_)
{
	http_client_update_fds();

#if LIBCURL_VERSION_NUM >= 0x070f04
	http_client.timeout = false;

	long timeout2;
	CURLMcode mcode = curl_multi_timeout(http_client.multi, &timeout2);
	if (mcode == CURLM_OK) {
		if (timeout2 >= 0 && timeout2 < 10)
			/* CURL 7.21.1 likes to report "timeout=0",
			   which means we're running in a busy loop.
			   Quite a bad idea to waste so much CPU.
			   Let's use a lower limit of 10ms. */
			timeout2 = 10;

		*timeout_ = timeout2;

		http_client.timeout = timeout2 >= 0;
	} else
		g_warning("curl_multi_timeout() failed: %s\n",
			  curl_multi_strerror(mcode));
#endif

	return FALSE;
}
Ejemplo n.º 8
0
/*
 * call-seq:
 * multi = Curl::Multi.new
 * easy1 = Curl::Easy.new('url')
 * easy2 = Curl::Easy.new('url')
 *
 * multi.add(easy1)
 * multi.add(easy2)
 *
 * multi.perform do
 *  # while idle other code my execute here
 * end
 *
 * Run multi handles, looping selecting when data can be transfered
 */
static VALUE ruby_curl_multi_perform(VALUE self) {
  CURLMcode mcode;
  ruby_curl_multi *rbcm;
  int maxfd, rc;
  fd_set fdread, fdwrite, fdexcep;

  long timeout;
  struct timeval tv = {0, 0};

  Data_Get_Struct(self, ruby_curl_multi, rbcm);
  //rb_gc_mark(self);

  rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );

  while(rbcm->running) { 
    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* load the fd sets from the multi handle */
    mcode = curl_multi_fdset(rbcm->handle, &fdread, &fdwrite, &fdexcep, &maxfd);
    if (mcode != CURLM_OK) {
      raise_curl_multi_error_exception(mcode);
    }

    /* get the curl suggested time out */
    mcode = curl_multi_timeout(rbcm->handle, &timeout);
    if (mcode != CURLM_OK) {
      raise_curl_multi_error_exception(mcode);
    }

    if (timeout == 0) { /* no delay */
      rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
      continue;
    }
    else if (timeout == -1) {
      timeout = 1; /* You must not wait too long 
                     (more than a few seconds perhaps) before 
                     you call curl_multi_perform() again */
    }

    if (rb_block_given_p()) {
      rb_yield(self);
    }
 
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = (timeout * 1000) % 1000000;

    rc = rb_thread_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &tv);
    if (rc < 0) {
      rb_raise(rb_eRuntimeError, "select(): %s", strerror(errno));
    }

    rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );

  }

  return Qnil;
}
void curl_perform_wait()
{
    long timeout_ms = -1;
    CURLMcode result = curl_multi_timeout(curl_handle, &timeout_ms);
    if (result != CURLM_OK) log_error("curl_multi_timeout error %d", result);

    if (timeout_ms < 1) timeout_ms = 1;

    int numfds = 0;
    result = curl_multi_wait(curl_handle, NULL, 0, (int)timeout_ms, &numfds);
    if (result != CURLM_OK) log_error("curl_multi_wait error %d", result);

    int numrunning = 0;
    result = curl_multi_perform(curl_handle, &numrunning);
    if (result != CURLM_OK) log_error("curl_multi_perform error %d", result);

    int pending = 0;
    CURLMsg *message;
    while ((message = curl_multi_info_read(curl_handle, &pending))) {
        switch (message->msg) {
            case CURLMSG_DONE:
            {
                const char* done_url;
                CURL* easy = message->easy_handle;
                curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &done_url);
                CURLcode code = message->data.result;
                printf("%s DONE\ncode:%d - %s\n", done_url, code,
                       curl_easy_strerror(code));

                struct curl_slist* list;
                curl_easy_getinfo(easy, CURLINFO_PRIVATE, &list);

                --remaining;

                if (--repeats)
                {
                    add_download(done_url);
                }
                
                curl_multi_remove_handle(curl_handle, easy);
                curl_easy_cleanup(easy);
                curl_slist_free_all(list);

                break;
            }
            default:
                log_error("CURLMSG default\n");
                abort();
        }
    }

    if (remaining == 0)
    {
        curl_multi_cleanup(curl_handle);
        exit(0);
    }
}
Ejemplo n.º 10
0
int64_t S3_get_request_context_timeout(S3RequestContext *requestContext)
{
    long timeout;

    if (curl_multi_timeout(requestContext->curlm, &timeout) != CURLM_OK) {
        timeout = 0;
    }
    
    return timeout;
}
Ejemplo n.º 11
0
 int set_timeout() {
         long timeout;
         if (curl_multi_timeout(m_handler, &timeout)) {
                 LOGE("@set_timeout curl_multi_timeout");
                 return -1;
         }
         if(timeout < 0)
                 timeout = MULTI_SELECT_TIMEOUT;
         m_timeout.tv_sec = timeout / 1000;
         m_timeout.tv_usec = (timeout % 1000) * 1000;
         return 0;
 }
Ejemplo n.º 12
0
Archivo: easy.c Proyecto: curl/curl
static CURLcode easy_transfer(struct Curl_multi *multi)
{
  bool done = FALSE;
  CURLMcode mcode = CURLM_OK;
  CURLcode result = CURLE_OK;

  while(!done && !mcode) {
    int still_running = 0;
    bool gotsocket = FALSE;

    mcode = Curl_multi_wait(multi, NULL, 0, 1000, NULL, &gotsocket);

    if(!mcode) {
      if(!gotsocket) {
        long sleep_ms;

        /* If it returns without any filedescriptor instantly, we need to
           avoid busy-looping during periods where it has nothing particular
           to wait for */
        curl_multi_timeout(multi, &sleep_ms);
        if(sleep_ms) {
          if(sleep_ms > 1000)
            sleep_ms = 1000;
          Curl_wait_ms((int)sleep_ms);
        }
      }

      mcode = curl_multi_perform(multi, &still_running);
    }

    /* only read 'still_running' if curl_multi_perform() return OK */
    if(!mcode && !still_running) {
      int rc;
      CURLMsg *msg = curl_multi_info_read(multi, &rc);
      if(msg) {
        result = msg->data.result;
        done = TRUE;
      }
    }
  }

  /* Make sure to return some kind of error if there was a multi problem */
  if(mcode) {
    result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
              /* The other multi errors should never happen, so return
                 something suitably generic */
              CURLE_BAD_FUNCTION_ARGUMENT;
  }

  return result;
}
Ejemplo n.º 13
0
/**
 * Initialises the Ecore_Con_Url library.
 * @return Number of times the library has been initialised without being
 *          shut down.
 * @ingroup Ecore_Con_Url_Group
 */
EAPI int
ecore_con_url_init(void)
{
#ifdef HAVE_CURL
   init_count++;

   if (init_count > 1) return init_count;

   if (!ECORE_CON_EVENT_URL_DATA)
     {
	ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
	ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
	ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
     }

   if (!curlm)
     {
	long ms;

	FD_ZERO(&_current_fd_set);
	if (curl_global_init(CURL_GLOBAL_NOTHING))
	  {
	     while (_url_con_list)
	       ecore_con_url_destroy(eina_list_data_get(_url_con_list));
	     return 0;
	  }

	curlm = curl_multi_init();
	if (!curlm)
	  {
	     while (_url_con_list)
	       ecore_con_url_destroy(eina_list_data_get(_url_con_list));

	     init_count--;
	     return 0;
	  }

	curl_multi_timeout(curlm, &ms);
	if (ms <= 0) ms = 1000;

	_curl_timeout = ecore_timer_add((double) ms / 1000, _ecore_con_url_idler_handler, (void *) 0xACE);
	ecore_timer_freeze(_curl_timeout);
     }
   return 1;
#else
   return 0;
#endif
}
Ejemplo n.º 14
0
static PyObject *
do_multi_timeout(CurlMultiObject *self)
{
    CURLMcode res;
    long timeout;

    if (check_multi_state(self, 1 | 2, "timeout") != 0) {
        return NULL;
    }

    res = curl_multi_timeout(self->multi_handle, &timeout);
    if (res != CURLM_OK) {
        CURLERROR_MSG("timeout failed");
    }

    /* Return number of millisecs until timeout */
    return Py_BuildValue("l", timeout);
}
Ejemplo n.º 15
0
struct timeval* http_get_timeout(void *d){
	struct http_data *data=(struct http_data*)d;
	long curl_timeo = -1;

	if(data->cm==NULL)
		return NULL;

	curl_multi_timeout(data->cm, &curl_timeo);

	if(curl_timeo >= 0) {
		data->timeout.tv_sec = curl_timeo / 1000;
		if(data->timeout.tv_sec > 1)
			data->timeout.tv_sec = 1;
		else
			data->timeout.tv_usec = (curl_timeo % 1000) * 1000;
	}

	return &data->timeout;
}
Ejemplo n.º 16
0
bool CCURLWrapper::Process()
{
    if (m_bDone)
        return false;
    
    if (m_lTimer > GetTime())
        return true;
    
    Perform();
    
    const long maxwait = 250; // msec
    long timeout = 0;
    
    CheckM(curl_multi_timeout(m_pCurlMulti, &timeout));
    timeout = std::min(timeout, maxwait);
    m_lTimer = GetTime() + timeout;
    
    CURLMsg *msg;
    int qleft;
    while ((msg = curl_multi_info_read(m_pCurlMulti, &qleft)) != NULL)
    {
        if (msg->msg == CURLMSG_DONE)
        {
            m_bDone = true;
            if (msg->data.result != CURLE_OK)
                m_Result = curl_easy_strerror(msg->data.result);
            else
            {
                long status;
                Check(curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &status));
                if ((status >= 400) && (status < 600)) // FTP/HTTP 4xx or 5xx code?
                    m_Result = "Error starting download"; // UNDONE?
            }
            break;
        }
    }
    
    return !m_bDone;
}
Ejemplo n.º 17
0
static int wait_perform()
{
    fd_set rd, wr, ex;
    int maxfd, nrunning;
    long timeout;
    CURLMcode errm;

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&ex);
    if (curl_multi_fdset(curl.multi, &rd, &wr, &ex, &maxfd) != CURLM_OK)
        maxfd = -1, timeout = 1000;
    else if (maxfd < 0)
        timeout = 100;  // as recommended by curl_multi_fdset(3)
    else {
        if (curl_multi_timeout(curl.multi, &timeout) != CURLM_OK)
            timeout = 1000;
        else if (timeout < 0)
            timeout = 10000;  // as recommended by curl_multi_timeout(3)
    }

    if (timeout > 0 && ! curl.perform_again) {
        struct timeval tval;
        tval.tv_sec  = (timeout / 1000);
        tval.tv_usec = (timeout % 1000) * 1000;

        if (select(maxfd + 1, &rd, &wr, &ex, &tval) < 0) return -1;
    }

    errm = curl_multi_perform(curl.multi, &nrunning);
    curl.perform_again = 0;
    if (errm == CURLM_CALL_MULTI_PERFORM) curl.perform_again = 1;
    else if (errm != CURLM_OK) { errno = multi_errno(errm); return -1; }

    if (nrunning < curl.nrunning) process_messages();
    return 0;
}
Ejemplo n.º 18
0
/**
 * Run all deferred multi calls and wait for the result
 * 
 * @param sdb the SimpleDB handle
 * @return the result
 */
int sdb_multi_run_and_wait(struct SDB* sdb)
{
	// This code was inspired by the implementation of readdir() in s3fs by Randy Rizun
	
	int running, r;
	
	while (curl_multi_perform(sdb->curl_multi, &running) == CURLM_CALL_MULTI_PERFORM) usleep(5);
	
	while (running) {
		fd_set read_fd_set;
		fd_set write_fd_set;
		fd_set exc_fd_set;
		
		FD_ZERO(&read_fd_set);
		FD_ZERO(&write_fd_set);
		FD_ZERO(&exc_fd_set);
		
		long ms;
		if ((r = curl_multi_timeout(sdb->curl_multi, &ms)) != CURLM_OK) return SDB_CURLM_ERROR(r);
		
		if (ms < 0) ms = 50;
		if (ms > 0) {
			struct timeval timeout;
			timeout.tv_sec = 1000 * ms / 1000000;
			timeout.tv_usec = 1000 * ms % 1000000;
			
			int max_fd;
			if ((r = curl_multi_fdset(sdb->curl_multi, &read_fd_set, &write_fd_set, &exc_fd_set, &max_fd)) != CURLM_OK) return SDB_CURLM_ERROR(r);
			
			if (select(max_fd + 1, &read_fd_set, &write_fd_set, &exc_fd_set, &timeout) == -1) return SDB_E_FD_ERROR;
		}
		
		while (curl_multi_perform(sdb->curl_multi, &running) == CURLM_CALL_MULTI_PERFORM) usleep(5);
	}
	
	return SDB_OK;
}
Ejemplo n.º 19
0
/*
 * Simply download a HTTP file.
 */
int main(void)
{
  CURL *http_handle;
  CURLM *multi_handle;

  int still_running; /* keep number of running handles */

  http_handle = curl_easy_init();

  /* set the options (I left out a few, you'll get the point anyway) */
  curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");

  /* init a multi stack */
  multi_handle = curl_multi_init();

  /* add the individual transfers */
  curl_multi_add_handle(multi_handle, http_handle);

  /* we start some action by calling perform right away */
  curl_multi_perform(multi_handle, &still_running);

  do {
    struct timeval timeout;
    int rc; /* select() return code */

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;

    long curl_timeo = -1;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* set a suitable timeout to play around with */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    curl_multi_timeout(multi_handle, &curl_timeo);
    if(curl_timeo >= 0) {
      timeout.tv_sec = curl_timeo / 1000;
      if(timeout.tv_sec > 1)
        timeout.tv_sec = 1;
      else
        timeout.tv_usec = (curl_timeo % 1000) * 1000;
    }

    /* get file descriptors from the transfers */
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */

    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

    switch(rc) {
    case -1:
      /* select error */
      still_running = 0;
      printf("select() returns error, this is badness\n");
      break;
    case 0:
    default:
      /* timeout or readable/writable sockets */
      curl_multi_perform(multi_handle, &still_running);
      break;
    }
  } while(still_running);

  curl_multi_cleanup(multi_handle);

  curl_easy_cleanup(http_handle);

  return 0;
}
Ejemplo n.º 20
0
static void
curl_main ()
{
  fd_set rs;
  fd_set ws;
  fd_set es;
  int max;
  struct GNUNET_NETWORK_FDSet nrs;
  struct GNUNET_NETWORK_FDSet nws;
  struct GNUNET_TIME_Relative delay;
  long timeout;
  int running;
  struct CURLMsg *msg;

  max = 0;
  FD_ZERO (&rs);
  FD_ZERO (&ws);
  FD_ZERO (&es);
  curl_multi_perform (multi, &running);
  if (running == 0)
  {
    GNUNET_assert (NULL != (msg = curl_multi_info_read (multi, &running)));
    if (msg->msg == CURLMSG_DONE)
    {
      if (msg->data.result != CURLE_OK)
      {
	fprintf (stderr,
		 "%s failed at %s:%d: `%s'\n",
		 "curl_multi_perform",
		__FILE__,
		__LINE__, curl_easy_strerror (msg->data.result));
	global_ret = 1;
      }
    }
    curl_multi_remove_handle (multi, curl);
    curl_multi_cleanup (multi);
    curl_easy_cleanup (curl);
    curl = NULL;
    multi = NULL;
    if (cbc.pos != strlen ("/hello_world"))
    {
      GNUNET_break (0);
      global_ret = 2;
    }
    if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    {
      GNUNET_break (0);
      global_ret = 3;
    }
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download complete, shutting down!\n");
    do_shutdown ();
    return;
  }
  GNUNET_assert (CURLM_OK == curl_multi_fdset (multi, &rs, &ws, &es, &max));
  if ( (CURLM_OK != curl_multi_timeout (multi, &timeout)) ||
       (-1 == timeout) )
    delay = GNUNET_TIME_UNIT_SECONDS;
  else
    delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, (unsigned int) timeout);
  GNUNET_NETWORK_fdset_copy_native (&nrs,
				    &rs,
				    max + 1);
  GNUNET_NETWORK_fdset_copy_native (&nws,
				    &ws,
				    max + 1);
  curl_task_id = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
					      delay,
					      &nrs,
					      &nws,
					      &curl_task,
					      NULL);
}
Ejemplo n.º 21
0
static void
tr_webThreadFunc( void * vsession )
{
    int unused;
    CURLM * multi;
    struct tr_web * web;
    int taskCount = 0;
    tr_session * session = vsession;

    /* try to enable ssl for https support; but if that fails,
     * try a plain vanilla init */
    if( curl_global_init( CURL_GLOBAL_SSL ) )
        curl_global_init( 0 );

    web = tr_new0( struct tr_web, 1 );
    web->close_mode = ~0;
    web->taskLock = tr_lockNew( );
    web->tasks = NULL;
    multi = curl_multi_init( );
    session->web = web;

    for( ;; )
    {
        long msec;
        CURLMsg * msg;
        CURLMcode mcode;
        struct tr_web_task * task;

        if( web->close_mode == TR_WEB_CLOSE_NOW )
            break;
        if( ( web->close_mode == TR_WEB_CLOSE_WHEN_IDLE ) && !taskCount )
            break;

        /* add tasks from the queue */
        tr_lockLock( web->taskLock );
        while(( task = tr_list_pop_front( &web->tasks )))
        {
            dbgmsg( "adding task to curl: [%s]", task->url );
            curl_multi_add_handle( multi, createEasy( session, task ));
            /*fprintf( stderr, "adding a task.. taskCount is now %d\n", taskCount );*/
            ++taskCount;
        }
        tr_lockUnlock( web->taskLock );

        /* maybe wait a little while before calling curl_multi_perform() */
        msec = 0;
        curl_multi_timeout( multi, &msec );
        if( msec < 0 )
            msec = THREADFUNC_MAX_SLEEP_MSEC;
        if( msec > 0 )
        {
            int usec;
            int max_fd;
            struct timeval t;
            fd_set r_fd_set, w_fd_set, c_fd_set;

            max_fd = 0;
            FD_ZERO( &r_fd_set );
            FD_ZERO( &w_fd_set );
            FD_ZERO( &c_fd_set );
            curl_multi_fdset( multi, &r_fd_set, &w_fd_set, &c_fd_set, &max_fd );

            if( msec > THREADFUNC_MAX_SLEEP_MSEC )
                msec = THREADFUNC_MAX_SLEEP_MSEC;

            usec = msec * 1000;
            t.tv_sec =  usec / 1000000;
            t.tv_usec = usec % 1000000;

            tr_select( max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t );
        }

        /* call curl_multi_perform() */
        do {
            mcode = curl_multi_perform( multi, &unused );
        } while( mcode == CURLM_CALL_MULTI_PERFORM );

        /* pump completed tasks from the multi */
        while(( msg = curl_multi_info_read( multi, &unused )))
        {
            if(( msg->msg == CURLMSG_DONE ) && ( msg->easy_handle != NULL ))
            {
                struct tr_web_task * task;
                CURL * e = msg->easy_handle;
                curl_easy_getinfo( e, CURLINFO_PRIVATE, (void*)&task );
                curl_easy_getinfo( e, CURLINFO_RESPONSE_CODE, &task->code );
                curl_multi_remove_handle( multi, e );
                curl_easy_cleanup( e );
/*fprintf( stderr, "removing a completed task.. taskCount is now %d (response code: %d, response len: %d)\n", taskCount, (int)task->code, (int)evbuffer_get_length(task->response) );*/
                tr_runInEventThread( task->session, task_finish_func, task );
                --taskCount;
            }
        }
    }

    /* cleanup */
    curl_multi_cleanup( multi );
    tr_lockFree( web->taskLock );
    tr_free( web );
    session->web = NULL;
}
Ejemplo n.º 22
0
Archivo: lib1531.c Proyecto: 2px/curl
int test(char *URL)
{
  CURL *easy;
  CURLM *multi_handle;
  int still_running; /* keep number of running handles */
  CURLMsg *msg; /* for picking up messages with the transfer status */
  int msgs_left; /* how many messages are left */

  /* Allocate one CURL handle per transfer */
  easy = curl_easy_init();

  /* init a multi stack */
  multi_handle = curl_multi_init();

  /* add the individual transfer */
  curl_multi_add_handle(multi_handle, easy);

  /* set the options (I left out a few, you'll get the point anyway) */
  curl_easy_setopt(easy, CURLOPT_URL, URL);
  curl_easy_setopt(easy, CURLOPT_POSTFIELDSIZE_LARGE,
                   (curl_off_t)testDataSize);
  curl_easy_setopt(easy, CURLOPT_POSTFIELDS, testData);

  /* we start some action by calling perform right away */
  curl_multi_perform(multi_handle, &still_running);

  do {
    struct timeval timeout;
    int rc; /* select() return code */
    CURLMcode mc; /* curl_multi_fdset() return code */

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;

    long curl_timeo = -1;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* set a suitable timeout to play around with */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    curl_multi_timeout(multi_handle, &curl_timeo);
    if(curl_timeo >= 0) {
      timeout.tv_sec = curl_timeo / 1000;
      if(timeout.tv_sec > 1)
        timeout.tv_sec = 1;
      else
        timeout.tv_usec = (curl_timeo % 1000) * 1000;
    }

    /* get file descriptors from the transfers */
    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    if(mc != CURLM_OK) {
      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
      break;
    }

    /* On success the value of maxfd is guaranteed to be >= -1. We call
       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
       to sleep 100ms, which is the minimum suggested value in the
       curl_multi_fdset() doc. */

    if(maxfd == -1) {
#ifdef _WIN32
      Sleep(100);
      rc = 0;
#else
      /* Portable sleep for platforms other than Windows. */
      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
      rc = select(0, NULL, NULL, NULL, &wait);
#endif
    }
    else {
      /* Note that on some platforms 'timeout' may be modified by select().
         If you need access to the original value save a copy beforehand. */
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    switch(rc) {
    case -1:
      /* select error */
      break;
    case 0: /* timeout */
    default: /* action */
      curl_multi_perform(multi_handle, &still_running);
      break;
    }
  } while(still_running);

  /* See how the transfers went */
  while((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
    if(msg->msg == CURLMSG_DONE) {
      printf("HTTP transfer completed with status %d\n", msg->data.result);
      break;
    }
  }

  curl_multi_cleanup(multi_handle);

  /* Free the CURL handles */
  curl_easy_cleanup(easy);

  return 0;
}
Ejemplo n.º 23
0
/*
 * call-seq:
 * multi = Curl::Multi.new
 * easy1 = Curl::Easy.new('url')
 * easy2 = Curl::Easy.new('url')
 *
 * multi.add(easy1)
 * multi.add(easy2)
 *
 * multi.perform do
 *  # while idle other code my execute here
 * end
 *
 * Run multi handles, looping selecting when data can be transfered
 */
VALUE ruby_curl_multi_perform(int argc, VALUE *argv, VALUE self) {
  CURLMcode mcode;
  ruby_curl_multi *rbcm;
  int maxfd, rc;
  fd_set fdread, fdwrite, fdexcep;
#ifdef _WIN32
  fd_set crt_fdread, crt_fdwrite, crt_fdexcep;
#endif

  long timeout_milliseconds;
  struct timeval tv = {0, 0};
  VALUE block = Qnil;

  rb_scan_args(argc, argv, "0&", &block);

  Data_Get_Struct(self, ruby_curl_multi, rbcm);

  timeout_milliseconds = cCurlMutiDefaulttimeout;

  rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
 
  do {
    while (rbcm->running) {

#ifdef HAVE_CURL_MULTI_TIMEOUT
      /* get the curl suggested time out */
      mcode = curl_multi_timeout(rbcm->handle, &timeout_milliseconds);
      if (mcode != CURLM_OK) {
        raise_curl_multi_error_exception(mcode);
      }
#else
      /* libcurl doesn't have a timeout method defined, initialize to -1 we'll pick up the default later */
      timeout_milliseconds = -1;
#endif

      if (timeout_milliseconds == 0) { /* no delay */
        rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
        continue;
      }
      else if (timeout_milliseconds < 0) {
        timeout_milliseconds = cCurlMutiDefaulttimeout; /* libcurl doesn't know how long to wait, use a default timeout */
      }

      if (timeout_milliseconds > cCurlMutiDefaulttimeout) {
        timeout_milliseconds = cCurlMutiDefaulttimeout; /* buggy versions libcurl sometimes reports huge timeouts... let's cap it */
      }

      tv.tv_sec  = 0; /* never wait longer than 1 second */
      tv.tv_usec = (int)(timeout_milliseconds * 1000); /* XXX: int is the right type for OSX, what about linux? */

      if (timeout_milliseconds == 0) { /* no delay */
        rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
        continue;
      }

      if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self);  }

      FD_ZERO(&fdread);
      FD_ZERO(&fdwrite);
      FD_ZERO(&fdexcep);
      /* load the fd sets from the multi handle */
      mcode = curl_multi_fdset(rbcm->handle, &fdread, &fdwrite, &fdexcep, &maxfd);
      if (mcode != CURLM_OK) {
        raise_curl_multi_error_exception(mcode);
      }

#ifdef _WIN32
      create_crt_fd(&fdread, &crt_fdread);
      create_crt_fd(&fdwrite, &crt_fdwrite);
      create_crt_fd(&fdexcep, &crt_fdexcep);
#endif

      rc = rb_thread_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &tv);

#ifdef _WIN32
      cleanup_crt_fd(&fdread, &crt_fdread);
      cleanup_crt_fd(&fdwrite, &crt_fdwrite);
      cleanup_crt_fd(&fdexcep, &crt_fdexcep);
#endif

      switch(rc) {
      case -1:
        rb_raise(rb_eRuntimeError, "select(): %s", strerror(errno));
        break;
      case 0:
        rb_curl_multi_read_info( self, rbcm->handle );
        if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self);  }
      default: 
        rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
        break;
      }
    }
    rb_curl_multi_read_info( self, rbcm->handle );
    if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self);  }
  } while( rbcm->running );
    
  return Qtrue;
}
Ejemplo n.º 24
0
static void
tr_webThreadFunc( void * vsession )
{
    CURLM * multi;
    struct tr_web * web;
    int taskCount = 0;
    struct tr_web_task * task;
    tr_session * session = vsession;

    /* try to enable ssl for https support; but if that fails,
     * try a plain vanilla init */
    if( curl_global_init( CURL_GLOBAL_SSL ) )
        curl_global_init( 0 );

    web = tr_new0( struct tr_web, 1 );
    web->close_mode = ~0;
    web->taskLock = tr_lockNew( );
    web->tasks = NULL;
    web->curl_verbose = getenv( "TR_CURL_VERBOSE" ) != NULL;
    web->cookie_filename = tr_buildPath( session->configDir, "cookies.txt", NULL );

    multi = curl_multi_init( );
    session->web = web;

    for( ;; )
    {
        long msec;
        int unused;
        CURLMsg * msg;
        CURLMcode mcode;

        if( web->close_mode == TR_WEB_CLOSE_NOW )
            break;
        if( ( web->close_mode == TR_WEB_CLOSE_WHEN_IDLE ) && ( web->tasks == NULL ) )
            break;

        /* add tasks from the queue */
        tr_lockLock( web->taskLock );
        while( web->tasks != NULL )
        {
            /* pop the task */
            task = web->tasks;
            web->tasks = task->next;
            task->next = NULL;

            dbgmsg( "adding task to curl: [%s]", task->url );
            curl_multi_add_handle( multi, createEasy( session, web, task ));
            /*fprintf( stderr, "adding a task.. taskCount is now %d\n", taskCount );*/
            ++taskCount;
        }
        tr_lockUnlock( web->taskLock );

        /* maybe wait a little while before calling curl_multi_perform() */
        msec = 0;
        curl_multi_timeout( multi, &msec );
        if( msec < 0 )
            msec = THREADFUNC_MAX_SLEEP_MSEC;
        if( session->isClosed )
            msec = 100; /* on shutdown, call perform() more frequently */
        if( msec > 0 )
        {
            int usec;
            int max_fd;
            struct timeval t;
            fd_set r_fd_set, w_fd_set, c_fd_set;

            max_fd = 0;
            FD_ZERO( &r_fd_set );
            FD_ZERO( &w_fd_set );
            FD_ZERO( &c_fd_set );
            curl_multi_fdset( multi, &r_fd_set, &w_fd_set, &c_fd_set, &max_fd );

            if( msec > THREADFUNC_MAX_SLEEP_MSEC )
                msec = THREADFUNC_MAX_SLEEP_MSEC;

            usec = msec * 1000;
            t.tv_sec =  usec / 1000000;
            t.tv_usec = usec % 1000000;
            tr_select( max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t );
        }

        /* call curl_multi_perform() */
        do {
            mcode = curl_multi_perform( multi, &unused );
        } while( mcode == CURLM_CALL_MULTI_PERFORM );

        /* pump completed tasks from the multi */
        while(( msg = curl_multi_info_read( multi, &unused )))
        {
            if(( msg->msg == CURLMSG_DONE ) && ( msg->easy_handle != NULL ))
            {
                double total_time;
                struct tr_web_task * task;
                long req_bytes_sent;
                CURL * e = msg->easy_handle;
                curl_easy_getinfo( e, CURLINFO_PRIVATE, (void*)&task );
                curl_easy_getinfo( e, CURLINFO_RESPONSE_CODE, &task->code );
                curl_easy_getinfo( e, CURLINFO_REQUEST_SIZE, &req_bytes_sent );
                curl_easy_getinfo( e, CURLINFO_TOTAL_TIME, &total_time );
                task->did_connect = task->code>0 || req_bytes_sent>0;
                task->did_timeout = !task->code && ( total_time >= task->timeout_secs );
                curl_multi_remove_handle( multi, e );
                curl_easy_cleanup( e );
/*fprintf( stderr, "removing a completed task.. taskCount is now %d (response code: %d, response len: %d)\n", taskCount, (int)task->code, (int)evbuffer_get_length(task->response) );*/
                tr_runInEventThread( task->session, task_finish_func, task );
                --taskCount;
            }
        }
    }

    /* Discard any remaining tasks.
     * This is rare, but can happen on shutdown with unresponsive trackers. */
    while( web->tasks != NULL ) {
        task = web->tasks;
        web->tasks = task->next;
        dbgmsg( "Discarding task \"%s\"", task->url );
        task_free( task );
    }

    /* cleanup */
    curl_multi_cleanup( multi );
    tr_lockFree( web->taskLock );
    tr_free( web->cookie_filename );
    tr_free( web );
    session->web = NULL;
}
Ejemplo n.º 25
0
int cetcd_multi_watch(cetcd_client *cli) {
    int           i, count;
    int           maxfd, left, added;
    long          timeout;
    long          backoff, backoff_max;
    fd_set        r, w, e;
    cetcd_array   *watchers;
    cetcd_watcher *watcher;
    CURLM         *mcurl;

    struct timeval tv;

    mcurl = curl_multi_init();
    watchers = &cli->watchers;
    count = cetcd_array_size(watchers);
    for (i = 0; i < count; ++i) {
        watcher = cetcd_array_get(watchers, i);
        curl_easy_setopt(watcher->curl, CURLOPT_PRIVATE, watcher);
        curl_multi_add_handle(mcurl, watcher->curl);
    }
    backoff = 100; /*100ms*/
    backoff_max = 1000; /*1 sec*/
    for(;;) {
        curl_multi_perform(mcurl, &left);
        if (left) {
            FD_ZERO(&r);
            FD_ZERO(&w);
            FD_ZERO(&e);
            curl_multi_fdset(mcurl, &r, &w, &e, &maxfd);
            curl_multi_timeout(mcurl, &timeout);
            if (timeout == -1) {
                timeout = 100; /*wait for 0.1 seconds*/
            }
            tv.tv_sec = timeout/1000;
            tv.tv_usec = (timeout%1000)*1000;

            /*TODO handle errors*/
            select(maxfd+1, &r, &w, &e, &tv);
        }
        added = cetcd_reap_watchers(cli, mcurl);
        if (added == 0 && left == 0) {
        /* It will call curl_multi_perform immediately if:
         * 1. left is 0
         * 2. a new attempt should be issued
         * It is expected to sleep a mount time between attempts.
         * So we fix this by increasing added counter only
         * when a new request should be issued.
         * When added is 0, maybe there are retring requests or nothing.
         * Either situations should wait before issuing the request.
         * */
            if (backoff < backoff_max) {
                backoff = 2 * backoff;
            } else {
                backoff = backoff_max;
            }
            tv.tv_sec = backoff/1000;
            tv.tv_usec = (backoff%1000) * 1000;
            select(1, 0, 0, 0, &tv);
        }
    }
    curl_multi_cleanup(mcurl);
    return count;
}
Ejemplo n.º 26
0
static void
gst_curl_multi_context_loop (gpointer thread_data)
{
  GstCurlMultiContext* thiz;
  gint rc;
  struct timeval timeout;
  int maxfd = -1;
  long curl_timeo = -1;
  fd_set fdread, fdwrite, fdexcep;

  thiz = (GstCurlMultiContext *) thread_data;

  g_mutex_lock (&thiz->mutex);
  /* Someone is holding a reference to us, but isn't using us so to avoid
   * unnecessary clock cycle wasting, sit in a conditional wait until woken.
   */
  while (thiz->sources == 0 && thiz->refcount > 0) {
    GST_DEBUG ("Entering wait state...");
    g_cond_wait (&thiz->signal, &thiz->mutex);
    GST_DEBUG ("Received wake up call!");
  }

  /* check the exit condition */
  if (thiz->refcount <= 0) {
    GST_DEBUG ("Exiting");
    g_mutex_unlock (&thiz->mutex);
    return;
  }

  FD_ZERO (&fdread);
  FD_ZERO (&fdwrite);
  FD_ZERO (&fdexcep);

  timeout.tv_sec = 1;
  timeout.tv_usec = 0;

  curl_multi_timeout (thiz->multi_handle, &curl_timeo);
  if (curl_timeo >= 0) {
  timeout.tv_sec = curl_timeo / 1000;
    if (timeout.tv_sec > 1) {
      timeout.tv_sec = 1;
    }
    else {
      timeout.tv_usec = (curl_timeo % 1000) * 1000;
    }
  }

  /* get file descriptors from the transfers */
  curl_multi_fdset (thiz->multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

  /* Because curl can possibly take some time here, be nice and let go of the
   * mutex so other threads can perform state/queue operations as we don't
   * care about those until the end of this. */
  g_mutex_unlock (&thiz->mutex);

  rc = select (maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);

  g_mutex_lock (&thiz->mutex);
  switch (rc) {
  case -1:
    /* select error */
    break;
  case 0:
  default:
    /* timeout or readable/writable sockets */
    curl_multi_perform (thiz->multi_handle, &thiz->sources);
    break;
  }

  gst_curl_multi_context_process_msgs (thiz);

  g_mutex_unlock(&thiz->mutex);
}
Ejemplo n.º 27
0
/*
 * Upload all files over HTTP/2, using the same physical connection!
 */
int main(int argc, char **argv)
{
  CURL *easy[NUM_HANDLES];
  CURLM *multi_handle;
  int i;
  int still_running; /* keep number of running handles */
  const char *filename = "index.html";

  if(argc > 1)
    /* if given a number, do that many transfers */
    num_transfers = atoi(argv[1]);

  if(argc > 2)
    /* if given a file name, upload this! */
    filename = argv[2];

  if(!num_transfers || (num_transfers > NUM_HANDLES))
    num_transfers = 3; /* a suitable low default */

  /* init a multi stack */
  multi_handle = curl_multi_init();

  for(i=0; i<num_transfers; i++) {
    easy[i] = curl_easy_init();
    /* set options */
    setup(easy[i], i, filename);

    /* add the individual transfer */
    curl_multi_add_handle(multi_handle, easy[i]);
  }

  curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);

  /* We do HTTP/2 so let's stick to one connection per host */
  curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1L);

  /* we start some action by calling perform right away */
  curl_multi_perform(multi_handle, &still_running);

  do {
    struct timeval timeout;
    int rc; /* select() return code */
    CURLMcode mc; /* curl_multi_fdset() return code */

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;

    long curl_timeo = -1;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* set a suitable timeout to play around with */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    curl_multi_timeout(multi_handle, &curl_timeo);
    if(curl_timeo >= 0) {
      timeout.tv_sec = curl_timeo / 1000;
      if(timeout.tv_sec > 1)
        timeout.tv_sec = 1;
      else
        timeout.tv_usec = (curl_timeo % 1000) * 1000;
    }

    /* get file descriptors from the transfers */
    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    if(mc != CURLM_OK)
    {
      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
      break;
    }

    /* On success the value of maxfd is guaranteed to be >= -1. We call
       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
       to sleep 100ms, which is the minimum suggested value in the
       curl_multi_fdset() doc. */

    if(maxfd == -1) {
#ifdef _WIN32
      Sleep(100);
      rc = 0;
#else
      /* Portable sleep for platforms other than Windows. */
      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
      rc = select(0, NULL, NULL, NULL, &wait);
#endif
    }
    else {
      /* Note that on some platforms 'timeout' may be modified by select().
         If you need access to the original value save a copy beforehand. */
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    switch(rc) {
    case -1:
      /* select error */
      break;
    case 0:
    default:
      /* timeout or readable/writable sockets */
      curl_multi_perform(multi_handle, &still_running);
      break;
    }
  } while(still_running);

  curl_multi_cleanup(multi_handle);

  for(i=0; i<num_transfers; i++)
    curl_easy_cleanup(easy[i]);

  return 0;
}
Ejemplo n.º 28
0
int main(void)
{
   CURL *curl;
   CURLM *mcurl;
   int still_running = 1;
   struct timeval mp_start;
   char mp_timedout = 0;
   struct WriteThis pooh;
   struct curl_slist* rcpt_list = NULL;

   pooh.counter = 0;

   curl_global_init(CURL_GLOBAL_DEFAULT);

   curl = curl_easy_init();
   if(!curl)
     return 1;

   mcurl = curl_multi_init();
   if(!mcurl)
     return 2;

   rcpt_list = curl_slist_append(rcpt_list, RECEPIENT);
   /* more addresses can be added here
      rcpt_list = curl_slist_append(rcpt_list, "*****@*****.**");
   */

   curl_easy_setopt(curl, CURLOPT_URL, "smtp://" SMTPSERVER SMTPPORT);
   curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME);
   curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
   curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
   curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM);
   curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list);
   curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0);
   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
   curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
   curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
   curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0);
   curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0);
   curl_multi_add_handle(mcurl, curl);

   mp_timedout = 0;
   mp_start = tvnow();

  /* we start some action by calling perform right away */
  curl_multi_perform(mcurl, &still_running);

  while(still_running) {
    struct timeval timeout;
    int rc; /* select() return code */

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;

    long curl_timeo = -1;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* set a suitable timeout to play around with */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    curl_multi_timeout(mcurl, &curl_timeo);
    if(curl_timeo >= 0) {
      timeout.tv_sec = curl_timeo / 1000;
      if(timeout.tv_sec > 1)
        timeout.tv_sec = 1;
      else
        timeout.tv_usec = (curl_timeo % 1000) * 1000;
    }

    /* get file descriptors from the transfers */
    curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */

    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

    if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
      fprintf(stderr, "ABORTING TEST, since it seems "
              "that it would have run forever.\n");
      break;
    }

    switch(rc) {
    case -1:
      /* select error */
      break;
    case 0: /* timeout */
    default: /* action */
      curl_multi_perform(mcurl, &still_running);
      break;
    }
  }

  curl_slist_free_all(rcpt_list);
  curl_multi_remove_handle(mcurl, curl);
  curl_multi_cleanup(mcurl);
  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return 0;
}
Ejemplo n.º 29
0
int test(char *URL)
{
  CURLM *cm = NULL;
  CURLSH *sh = NULL;
  CURL *ch = NULL;
  int unfinished;

  cm = curl_multi_init();
  if(!cm)
    return 1;
  sh = curl_share_init();
  if(!sh)
    goto cleanup;

  curl_share_setopt(sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
  curl_share_setopt(sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);

  ch = curl_easy_init();
  if(!ch)
    goto cleanup;

  curl_easy_setopt(ch, CURLOPT_SHARE, sh);
  curl_easy_setopt(ch, CURLOPT_URL, URL);
  curl_easy_setopt(ch, CURLOPT_COOKIEFILE, "log/cookies1905");
  curl_easy_setopt(ch, CURLOPT_COOKIEJAR, "log/cookies1905");

  curl_multi_add_handle(cm, ch);

  unfinished = 1;
  while(unfinished) {
    int MAX = 0;
    long max_tout;
    fd_set R, W, E;
    struct timeval timeout;

    FD_ZERO(&R);
    FD_ZERO(&W);
    FD_ZERO(&E);
    curl_multi_perform(cm, &unfinished);

    curl_multi_fdset(cm, &R, &W, &E, &MAX);
    curl_multi_timeout(cm, &max_tout);

    if(max_tout > 0) {
      timeout.tv_sec = max_tout / 1000;
      timeout.tv_usec = (max_tout % 1000) * 1000;
    }
    else {
      timeout.tv_sec = 0;
      timeout.tv_usec = 1000;
    }

    select(MAX + 1, &R, &W, &E, &timeout);
  }

  curl_easy_setopt(ch, CURLOPT_COOKIELIST, "FLUSH");
  curl_easy_setopt(ch, CURLOPT_SHARE, NULL);

  curl_multi_remove_handle(cm, ch);
  cleanup:
  curl_easy_cleanup(ch);
  curl_share_cleanup(sh);
  curl_multi_cleanup(cm);

  return 0;
}
Ejemplo n.º 30
0
int main(void)
{
  CURL *curl;
  CURLM *mcurl;
  int still_running = 1;
  struct timeval mp_start;

  curl_global_init(CURL_GLOBAL_DEFAULT);

  curl = curl_easy_init();
  if(!curl)
    return 1;

  mcurl = curl_multi_init();
  if(!mcurl)
    return 2;

  /* Set username and password */
  curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
  curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");

  /* This will fetch message 1 from the user's inbox */
  curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX/;UID=1");

  /* Tell the multi stack about our easy handle */
  curl_multi_add_handle(mcurl, curl);

  /* Record the start time which we can use later */
  mp_start = tvnow();

  /* We start some action by calling perform right away */
  curl_multi_perform(mcurl, &still_running);

  while(still_running) {
    struct timeval timeout;
    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;
    int rc;
    CURLMcode mc; /* curl_multi_fdset() return code */

    long curl_timeo = -1;

    /* Initialise the file descriptors */
    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* Set a suitable timeout to play around with */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    curl_multi_timeout(mcurl, &curl_timeo);
    if(curl_timeo >= 0) {
      timeout.tv_sec = curl_timeo / 1000;
      if(timeout.tv_sec > 1)
        timeout.tv_sec = 1;
      else
        timeout.tv_usec = (curl_timeo % 1000) * 1000;
    }

    /* get file descriptors from the transfers */
    mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);

    if(mc != CURLM_OK)
    {
      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
      break;
    }

    /* On success the value of maxfd is guaranteed to be >= -1. We call
       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
       to sleep 100ms, which is the minimum suggested value in the
       curl_multi_fdset() doc. */

    if(maxfd == -1) {
#ifdef _WIN32
      Sleep(100);
      rc = 0;
#else
      /* Portable sleep for platforms other than Windows. */
      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
      rc = select(0, NULL, NULL, NULL, &wait);
#endif
    }
    else {
      /* Note that on some platforms 'timeout' may be modified by select().
         If you need access to the original value save a copy beforehand. */
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
      fprintf(stderr,
              "ABORTING: Since it seems that we would have run forever.\n");
      break;
    }

    switch(rc) {
    case -1:  /* select error */
      break;
    case 0:   /* timeout */
    default:  /* action */
      curl_multi_perform(mcurl, &still_running);
      break;
    }
  }

  /* Always cleanup */
  curl_multi_remove_handle(mcurl, curl);
  curl_multi_cleanup(mcurl);
  curl_easy_cleanup(curl);
  curl_global_cleanup();

  return 0;
}