Beispiel #1
0
core::curl_handler::connection_context::connection_context(milliseconds_t _timeout, curl_handler* _curl_handler, CURL* _easy_handle, const completion_handler_t& _completion_handler)
    : timeout_(_timeout)
    , curl_handler_(_curl_handler)
    , easy_handle_(_easy_handle)
    , completion_handler_(_completion_handler)
    , socket_(0)
    , event_(nullptr)
{
    const auto tv = make_timeval(timeout_);
    timeout_event_ = evtimer_new(curl_handler_->event_base_, event_timeout_callback, this);
    evtimer_add(timeout_event_, &tv);
}
Beispiel #2
0
	bool winsock2_streambuf::wait_state(time_point until, int fstate)
	{
		int wsaerr;
		int solen;

	again:
		struct timeval timeout;
		make_timeval(timeout, until - time_point::clock::now());

		fd_set read_set, write_set, err_set;
		fd_set * pread_set = nullptr;
		fd_set * pwrite_set = nullptr;

		if (fstate & freadable)
		{
			pread_set = &read_set;
			FD_ZERO(pread_set);
			FD_SET(m_sockhandle, pread_set);
		}

		if (fstate & fwritable)
		{
			pwrite_set = &write_set;
			FD_ZERO(pwrite_set);
			FD_SET(m_sockhandle, pwrite_set);
		}
		
		FD_ZERO(&err_set);
		FD_SET(m_sockhandle, &err_set);

		int res = ::select(m_sockhandle + 1, pread_set, pwrite_set, &err_set, &timeout);
		if (res == 0) // timeout
		{
			m_lasterror = make_error_code(sock_errc::timeout);
			return false;
		}

		if (res == -1) goto sockerror;
		assert(res >= 1);

		solen = sizeof(wsaerr);
		res = ::getsockopt(m_sockhandle, SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&wsaerr), &solen);
		if (res != 0)    goto sockerror;
		if (wsaerr != 0) goto wsaerror;

		return true;

	sockerror:
		wsaerr = ::WSAGetLastError();
	wsaerror:
		if (rw_error(-1, wsaerr, m_lasterror)) return false;
		goto again;
	}
Beispiel #3
0
	bool bsdsock_streambuf::wait_state(time_point until, int fstate)
	{
		int err;
		sockoptlen_t solen;

	again:
		struct timeval timeout;
		make_timeval(timeout, until - time_point::clock::now());

		fd_set read_set, write_set;
		fd_set * pread_set = nullptr;
		fd_set * pwrite_set = nullptr;

		if (fstate & freadable)
		{
			pread_set = &read_set;
			FD_ZERO(pread_set);
			FD_SET(m_sockhandle, pread_set);
		}

		if (fstate & fwritable)
		{
			pwrite_set = &write_set;
			FD_ZERO(pwrite_set);
			FD_SET(m_sockhandle, pwrite_set);
		}
		
		int res = ::select(m_sockhandle + 1, pread_set, pwrite_set, nullptr, &timeout);
		if (res == 0) // timeout
		{
			m_lasterror = make_error_code(sock_errc::timeout);
			return false;
		}

		if (res == -1) goto sockerror;
		
		solen = sizeof(err);
		res = ::getsockopt(m_sockhandle, SOL_SOCKET, SO_ERROR, &err, &solen);
		if (res != 0) goto sockerror;
		if (err != 0) goto error;

		return true;

	sockerror:
		err = errno;
	error:
		if (rw_error(-1, err, m_lasterror)) return false;
		goto again;		
	}
Beispiel #4
0
static void
set_alarm (void)
{
  if (atimers)
    {
#ifdef HAVE_SETITIMER
      struct itimerval it;
#endif
      struct timespec now, interval;

#ifdef HAVE_ITIMERSPEC
      if (0 <= timerfd || alarm_timer_ok)
	{
	  struct itimerspec ispec;
	  ispec.it_value = atimers->expiration;
	  ispec.it_interval.tv_sec = ispec.it_interval.tv_nsec = 0;
# ifdef HAVE_TIMERFD
	  if (timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0) == 0)
	    {
	      add_timer_wait_descriptor (timerfd);
	      return;
	    }
# endif
	  if (alarm_timer_ok
	      && timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
	    return;
	}
#endif

      /* Determine interval till the next timer is ripe.
	 Don't set the interval to 0; this disables the timer.  */
      now = current_timespec ();
      interval = (timespec_cmp (atimers->expiration, now) <= 0
		  ? make_timespec (0, 1000 * 1000)
		  : timespec_sub (atimers->expiration, now));

#ifdef HAVE_SETITIMER

      memset (&it, 0, sizeof it);
      it.it_value = make_timeval (interval);
      setitimer (ITIMER_REAL, &it, 0);
#else /* not HAVE_SETITIMER */
      alarm (max (interval.tv_sec, 1));
#endif /* not HAVE_SETITIMER */
    }
}
Beispiel #5
0
static void
set_alarm (void)
{
  if (atimers)
    {
#ifdef HAVE_SETITIMER
      struct itimerval it;
#endif
      EMACS_TIME now, interval;

#ifdef HAVE_ITIMERSPEC
      if (alarm_timer_ok)
	{
	  struct itimerspec ispec;
	  ispec.it_value = atimers->expiration;
	  ispec.it_interval.tv_sec = ispec.it_interval.tv_nsec = 0;
	  if (timer_settime (alarm_timer, 0, &ispec, 0) == 0)
	    return;
	}
#endif

      /* Determine interval till the next timer is ripe.
	 Don't set the interval to 0; this disables the timer.  */
      now = current_emacs_time ();
      interval = (EMACS_TIME_LE (atimers->expiration, now)
		  ? make_emacs_time (0, 1000 * 1000)
		  : sub_emacs_time (atimers->expiration, now));

#ifdef HAVE_SETITIMER

      memset (&it, 0, sizeof it);
      it.it_value = make_timeval (interval);
      setitimer (ITIMER_REAL, &it, 0);
#else /* not HAVE_SETITIMER */
      alarm (max (EMACS_SECS (interval), 1));
#endif /* not HAVE_SETITIMER */
    }
}
Beispiel #6
0
	bool winsock2_streambuf::do_sockconnect(handle_type sock, const addrinfo_type * addr)
	{
		int wsaerr, res, solen;
		StateType prevstate;
		bool closesock, pubres; // в случае ошибки закрыть сокет
		auto until = time_point::clock::now() + m_timeout;
		
		prevstate = Closed;
		m_lasterror.clear();

		res = ::connect(sock, addr->ai_addr, addr->ai_addrlen);
		if (res == 0) goto connected; // connected immediately
		assert(res == SOCKET_ERROR);

		if ((wsaerr = ::WSAGetLastError()) != WSAEWOULDBLOCK)
			goto wsaerror;

	again:
		pubres = publish_connecting(sock);
		if (!pubres) goto intrreq;

		timeval timeout;
		make_timeval(timeout, until - time_point::clock::now());

		fd_set write_set, err_set;
		FD_ZERO(&write_set);
		FD_ZERO(&err_set);
		FD_SET(sock, &write_set);
		FD_SET(sock, &err_set);

		prevstate = Connecting;
		res = ::select(0, nullptr, &write_set, &err_set, &timeout);
		if (res == 0) // timeout
		{
			wsaerr = WSAETIMEDOUT;
			goto wsaerror;
		}

		if (res == SOCKET_ERROR) goto sockerror;
		assert(res == 1);

		solen = sizeof(wsaerr);
		res = ::getsockopt(sock, SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&wsaerr), &solen);
		if (res != 0)    goto sockerror;
		if (wsaerr != 0) goto wsaerror;
		
	connected:
		pubres = publish_opened(sock, prevstate);
		if (!pubres) goto intrreq;

		m_lasterror.clear();
		return true;

	sockerror:
		wsaerr = ::WSAGetLastError();
	wsaerror:
		pubres = m_state.compare_exchange_strong(prevstate, Closed, std::memory_order_relaxed);
		// произошла ошибка, она может результатом closesocket из interrupt
		// если мы успешно перешли в Closed - interrupt'а не было, а значит это обычная ошибка
		if (pubres)
		{
			if (wsaerr == WSAEINTR) goto again;
			
			closesock = true;
			if (wsaerr == WSAETIMEDOUT) m_lasterror = make_error_code(sock_errc::timeout);
			else                        m_lasterror.assign(wsaerr, std::system_category());
		}
		else intrreq:
		{
			// было прерывание, если оно было до publish_connecting, то мы должны закрыть сокет
			// иначе сокет был закрыт из interrupt
			m_lasterror = std::make_error_code(std::errc::interrupted);
			// такое возможно, только если мы не смогли опубликовать publish_connecting,
			closesock = prevstate == Closed;
		}

		if (closesock)
		{
			res = ::closesocket(m_sockhandle);
			assert(res == 0 || (res = ::WSAGetLastError()) == 0);
		}

		m_sockhandle = INVALID_SOCKET;
		return false;
	}
Beispiel #7
0
	bool bsdsock_streambuf::do_sockconnect(handle_type sock, const addrinfo_type * addr)
	{
		int err, res, pipefd[2]; // self pipe trick. [0] readable, [1] writable
		bool closepipe, pubres;  // должны ли мы закрыть pipe, или он был закрыт в interrupt
		sockoptlen_t solen;
		StateType prevstate;
		auto until = time_point::clock::now() + m_timeout;
		
		prevstate = Closed;
		m_lasterror.clear();

		res = ::pipe(pipefd);
		if (res != 0) goto sockerror;
		
		res = ::connect(sock, addr->ai_addr, addr->ai_addrlen);
		if (res == 0) goto connected; // connected immediately
		assert(res == -1);

		if ((err = errno) != EINPROGRESS)
			goto error;

	again:
		pubres = publish_connecting(pipefd[1]);
		if (!pubres) goto intrreq;
	
		struct timeval timeout;
		make_timeval(timeout, until - time_point::clock::now());

		fd_set write_set, read_set;
		FD_ZERO(&write_set);
		FD_ZERO(&read_set);
		FD_SET(sock, &write_set);
		FD_SET(pipefd[0], &read_set);
		
		prevstate = Connecting;
		res = ::select(std::max(sock, pipefd[0]) + 1, &read_set, &write_set, nullptr, &timeout);
		if (res == 0) // timeout
		{
			err = ETIMEDOUT;
			goto error;
		}

		if (res == -1) goto sockerror;
		assert(res >= 1);
		
		solen = sizeof(err);
		res = ::getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &solen);
		if (res != 0) goto sockerror;
		if (err != 0) goto error;
		
	connected:
		pubres = publish_opened(sock, prevstate);
		if (!pubres) goto intrreq;

		m_lasterror.clear();
		return true;

	sockerror:
		err = errno;
	error:
		pubres = m_state.compare_exchange_strong(prevstate, Closed, std::memory_order_relaxed);
		// произошла ошибка, она может результатом closesocket из interrupt
		// если мы успешно перешли в Closed - interrupt'а не было, а значит это обычная ошибка
		if (pubres)
		{
			if (err == EINTR) goto again;
			
			closepipe = true;
			if (err == ETIMEDOUT) m_lasterror = make_error_code(sock_errc::timeout);
			else                  m_lasterror.assign(err, std::generic_category());
		}
		else intrreq:
		{
			// было прерывание, если оно было до publish_connecting, то мы должны закрыть pipefd[1]
			// иначе pipefd[1] был закрыт внутри interrupt
			m_lasterror = std::make_error_code(std::errc::interrupted);
			// такое возможно, только если мы не смогли опубликовать publish_connecting,
			closepipe = prevstate == Closed;
		}

		if (closepipe) ::close(pipefd[1]);
		::close(pipefd[0]);
		
		res = ::close(sock);
		assert(res == 0 || (res = errno) == 0);
		
		m_sockhandle = -1;
		return false;
	}
Beispiel #8
0
static enum profiler_cpu_running
setup_cpu_timer (Lisp_Object sampling_interval)
{
  struct sigaction action;
  struct itimerval timer;
  struct timespec interval;
  int billion = 1000000000;

  if (! RANGED_INTEGERP (1, sampling_interval,
			 (TYPE_MAXIMUM (time_t) < EMACS_INT_MAX / billion
			  ? ((EMACS_INT) TYPE_MAXIMUM (time_t) * billion
			     + (billion - 1))
			  : EMACS_INT_MAX)))
    return NOT_RUNNING;

  current_sampling_interval = XINT (sampling_interval);
  interval = make_timespec (current_sampling_interval / billion,
			    current_sampling_interval % billion);
  emacs_sigaction_init (&action, deliver_profiler_signal);
  sigaction (SIGPROF, &action, 0);

#ifdef HAVE_ITIMERSPEC
  if (! profiler_timer_ok)
    {
      /* System clocks to try, in decreasing order of desirability.  */
      static clockid_t const system_clock[] = {
#ifdef CLOCK_THREAD_CPUTIME_ID
	CLOCK_THREAD_CPUTIME_ID,
#endif
#ifdef CLOCK_PROCESS_CPUTIME_ID
	CLOCK_PROCESS_CPUTIME_ID,
#endif
#ifdef CLOCK_MONOTONIC
	CLOCK_MONOTONIC,
#endif
	CLOCK_REALTIME
      };
      int i;
      struct sigevent sigev;
      sigev.sigev_value.sival_ptr = &profiler_timer;
      sigev.sigev_signo = SIGPROF;
      sigev.sigev_notify = SIGEV_SIGNAL;

      for (i = 0; i < ARRAYELTS (system_clock); i++)
	if (timer_create (system_clock[i], &sigev, &profiler_timer) == 0)
	  {
	    profiler_timer_ok = 1;
	    break;
	  }
    }

  if (profiler_timer_ok)
    {
      struct itimerspec ispec;
      ispec.it_value = ispec.it_interval = interval;
      if (timer_settime (profiler_timer, 0, &ispec, 0) == 0)
	return TIMER_SETTIME_RUNNING;
    }
#endif

#ifdef HAVE_SETITIMER
  timer.it_value = timer.it_interval = make_timeval (interval);
  if (setitimer (ITIMER_PROF, &timer, 0) == 0)
    return SETITIMER_RUNNING;
#endif

  return NOT_RUNNING;
}