//==============================================================================
void QueuedTrajectoryExecutor::cancel()
{
  std::lock_guard<std::mutex> lock(mMutex);
  DART_UNUSED(lock); // Suppress unused variable warning

  std::exception_ptr cancel
      = std::make_exception_ptr(std::runtime_error("Trajectory canceled."));

  if (mInProgress)
  {
    mExecutor->cancel();

    // Set our own exception, since cancel may not be supported
    auto promise = mPromiseQueue.front();
    mPromiseQueue.pop();
    promise->set_exception(cancel);

    mInProgress = false;
  }

  // Trajectory and promise queue are now the same length
  while (!mPromiseQueue.empty())
  {
    auto promise = mPromiseQueue.front();
    mPromiseQueue.pop();
    promise->set_exception(cancel);

    mTrajectoryQueue.pop();
  }

  mFuture = std::future<void>();
}
예제 #2
0
void semantics_instr(char* input, unsigned int in_size, char** output, unsigned int* out_size) {
    clear_exception();
#ifdef GDSL_X86
    struct options options;
    options_init(&options);
#endif

    state_t state = gdsl_init();
    gdsl_set_code(state, input, in_size, 0);

    if(setjmp(*gdsl_err_tgt(state))) {
        snprintf(error_message, sizeof(error_message), "decode failed: %s", gdsl_get_error_message(state));
        set_exception();
        goto cleanup;
    }

#ifdef GDSL_X86
    int_t config = 0;
    config |= gdsl_config_mode64(state)*options.mode64;
    config |= gdsl_config_default_opnd_sz_32(state)*options.default_opnd_sz_32;

    obj_t insn = gdsl_decode(state, config);
#else
    obj_t insn = gdsl_decode(state, gdsl_config_default(state));
#endif

    gdsl_get_ip(state);

    string_t fmt = gdsl_merge_rope(state, gdsl_pretty(state, insn)); /* string_t is a typedef for char* */

    if(setjmp(*gdsl_err_tgt(state))) {
        snprintf(error_message, sizeof(error_message), "translate failed: %s", gdsl_get_error_message(state));
        set_exception();
        goto cleanup;
    }

    obj_t rreil = gdsl_translate(state, insn);

    fmt = gdsl_merge_rope(state, gdsl_rreil_pretty(state, rreil));
    size_t outputSize = strlen(fmt)+1;
    *output = malloc(outputSize);
    strncpy(*output, fmt, outputSize);
    *out_size = outputSize - 1; // Python expects size without null...
    cleanup:

    gdsl_reset_heap(state);

    gdsl_destroy(state);

}
예제 #3
0
    inline void on_success(Executor &exec)
    {
        auto pipe = this->pipe;

        auto buffer  = this->buffer;
        auto promise = this->promise;

        boost::asio::async_read(*pipe, *buffer,
                [pipe, buffer, promise](const boost::system::error_code& ec, std::size_t size)
                {
                    if (ec && (ec.value() != ENOENT))
                    {
                        std::error_code e(ec.value(), std::system_category());
                        promise->set_exception(std::make_exception_ptr(process_error(e)));
                    }
                    else
                    {
                        std::istream is (buffer.get());
                        Type arg;
                        arg.resize(buffer->size());
                        is.read(&*arg.begin(), buffer->size());
                        promise->set_value(std::move(arg));
                    }
                });

        std::move(*pipe).sink().close();
        this->pipe = nullptr;
    }
예제 #4
0
    inline void on_success(Executor &exec)
    {
        auto  pipe              = this->pipe;
        if (this->promise)
        {
            auto promise = this->promise;

            boost::asio::async_write(*pipe, buf,
                [pipe, promise](const boost::system::error_code & ec, std::size_t)
                {
                    if (ec && (ec.value() != EBADF) && (ec.value() != EPERM) && (ec.value() != ENOENT))
                    {
                        std::error_code e(ec.value(), std::system_category());
                        promise->set_exception(std::make_exception_ptr(process_error(e)));
                    }
                    else
                        promise->set_value();
                });
        }
        else
            boost::asio::async_write(*pipe, buf,
                [pipe](const boost::system::error_code&ec, std::size_t size){});

        std::move(*pipe).source().close();

        this->pipe = nullptr;
    }
예제 #5
0
    inline void on_success(Executor &exec)
    {
        auto pipe = this->pipe;

        if (this->promise)
        {
            auto promise = this->promise;

            boost::asio::async_write(*pipe, buf,
                [promise](const boost::system::error_code & ec, std::size_t)
                {
                    if (ec && (ec.value() != ::boost::detail::winapi::ERROR_BROKEN_PIPE_))
                    {
                        std::error_code e(ec.value(), std::system_category());
                        promise->set_exception(std::make_exception_ptr(std::system_error(e)));
                    }
                    promise->set_value();
                });
        }
        else
            boost::asio::async_write(*pipe, buf,
                [pipe](const boost::system::error_code&ec, std::size_t size){});

        this->pipe = nullptr;
    }
예제 #6
0
 void run_task() noexcept {
   try {
     run();
   } catch (...) {
     set_exception(std::current_exception());
   }
 }
예제 #7
0
/* Poll the answer of the separate thread that runs the binding process.
Returns NULL in case of error, Py_None for timeout, and the LDAPConnection
object if successfully finished the binding. */
static PyObject *
binding(LDAPConnectIter *self) {
	int rc;

	if (self->bind_inprogress == 0) {
		/* First call of bind. */
		rc = LDAP_bind(self->conn->ld, self->info, NULL, &(self->message_id));
		if (rc != LDAP_SUCCESS) {
			set_exception(self->conn->ld, rc);
			return NULL;
		}
		self->bind_inprogress = 1;
		Py_RETURN_NONE;
	} else {
		if (self->async) {
			rc = WaitForSingleObject(self->info->thread, 10);
		} else {
			rc = WaitForSingleObject(self->info->thread, INFINITE);
		}
		switch (rc) {
		case WAIT_TIMEOUT:
			Py_RETURN_NONE;
		case WAIT_OBJECT_0:
			GetExitCodeThread(self->info->thread, &rc);
			CloseHandle(self->info->thread);
			if (rc != LDAP_SUCCESS) {
				/* The ldap_connect is failed. Set a Python error. */
				set_exception(self->conn->ld, rc);
				return NULL;
			}
			/* The binding is successfully finished. */
			self->bind_inprogress = 0;
			self->conn->closed = 0;
			Py_INCREF((PyObject *)self->conn);
			return (PyObject *)self->conn;
		default:
			/* The thread is failed. */
			PyErr_BadInternalCall();
			return NULL;
		}
	}
}
 std::future<void> async(_Function&& work, _Args&&... args) {
     auto promise_ptr = std::make_shared<std::promise<void>>();
     do {
         if (std::this_thread::get_id() != thread_.get_id()) {
             std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
             if (!is_running_) {
                 throw std::runtime_error("Not running");
             }
             std::lock_guard<std::mutex> lock(works_mutex_);
             works_.push_back([=]() {
                 try {
                     work(args...);
                     promise_ptr->set_value();
                 }
                 catch (...) {
                     promise_ptr->set_exception(std::current_exception());
                 }
             });
             workable_.notify_all();
         }
         else {
             if (!is_running_) {
                 throw std::runtime_error("Not running");
             }
             std::lock_guard<std::mutex> lock(works_mutex_);
             works_.push_back([=]() {
                 try {
                     work(args...);
                     promise_ptr->set_value();
                 }
                 catch (...) {
                     promise_ptr->set_exception(std::current_exception());
                 }
             });
             workable_.notify_all();
         }
     } while (0);
     return promise_ptr->get_future();
 }
예제 #9
0
void LibUSB::Transfer::AsyncStart()
{

	if (m_AsynchronousTransferPending)
	{

		// Cannot change this right now.
		throw std::logic_error("LibUSB::Transfer::AsyncStart() - Method cannot be called while an asynchronous transfer is already in progress!");

	}

	// Set the transfer-in-progress flag.
	m_AsynchronousTransferPending = true;

	// Create a promise that will be used to return our copy of the Transfer Implmentation
	auto TransferPromise = std::make_shared<std::promise<std::shared_ptr<LibUSB::TransferImpl>>>();

	m_TransferFuture = TransferPromise->get_future();

	auto pPromisePending = std::make_shared<bool>(true);
	
	// Share a boolean as a signal.
	m_TransferThreadRunning = pPromisePending;
	
	std::shared_ptr<LibUSB::TransferImpl> pTransferImplementation = m_pTransferImpl;

	std::thread transferThread([=]()
				{
					bool Result = false;

					try
					{
						pTransferImplementation->Start();
						TransferPromise->set_value(pTransferImplementation);
					}
					catch (...)
					{
						TransferPromise->set_exception(std::current_exception());
					
					}

					*pPromisePending = false;
					
				});

	// Let it complete.
	transferThread.detach();
	
}
예제 #10
0
/// returns a future which will be set once the msg is processed
std::future<bool> TaskThreadPool::checked_push( const msg& msg )
{
  auto promise = std::make_shared<std::promise<bool>>();
  auto ret = promise->get_future();
  _msg_queue.push( [=]() {
    try
    {
      msg();
      promise->set_value( true );
    }
    catch ( ... )
    {
      promise->set_exception( std::current_exception() );
    }
  } );
  return ret;
}
//==============================================================================
void QueuedTrajectoryExecutor::step(
    const std::chrono::system_clock::time_point& timepoint)
{
  mExecutor->step(timepoint);

  std::lock_guard<std::mutex> lock(mMutex);
  DART_UNUSED(lock); // Suppress unused variable warning

  // If a trajectory was executing, check if it has finished
  if (mInProgress)
  {
    // Return if the trajectory is still executing
    if (mFuture.wait_for(std::chrono::seconds(0)) != std::future_status::ready)
      return;

    mInProgress = false;

    // The promise corresponding to the trajectory that just finished must be
    // at the front of its queue.
    auto promise = mPromiseQueue.front();
    mPromiseQueue.pop();

    // Propagate the future's value or exception to the caller
    try
    {
      mFuture.get();
      promise->set_value();
    }
    catch (const std::exception& e)
    {
      promise->set_exception(std::current_exception());
      cancel();
    }
  }

  // No trajectory currently executing, execute a trajectory from the queue
  if (!mTrajectoryQueue.empty())
  {
    trajectory::ConstTrajectoryPtr traj = mTrajectoryQueue.front();
    mTrajectoryQueue.pop();

    mFuture = mExecutor->execute(std::move(traj));
    mInProgress = true;
  }
}
예제 #12
0
파일: g2future.hpp 프로젝트: slug404/g3log
std::future<typename std::result_of<Func()>::type> spawn_task(Func func, BgWorker* worker)
{
    typedef typename std::result_of<Func()>::type result_type;
    typedef std::packaged_task<result_type()> task_type;

    if (nullptr == worker) {
        auto p = std::make_shared<std::promise<result_type>>();
        std::future<result_type> future_result = p->get_future();
        p->set_exception(std::make_exception_ptr(std::runtime_error("nullptr instantiated worker")));
        return future_result;
    }

    task_type task(std::move(func));

    std::future<result_type> result = task.get_future();
    worker->send(MoveOnCopy<task_type>(std::move(task)));
    return std::move(result);
}
예제 #13
0
파일: main.cpp 프로젝트: longshadian/estl
int main()
{
    std::future<int> f{};
    try {
        auto p = std::make_shared<std::promise<int>>();
        f = p->get_future();
        //p->set_value(2222);
        p->set_exception(std::current_exception());
        p = nullptr;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    } catch (const std::exception& e) {
        std::cout << e.what() << " xxxx\n";
        return 0;
    }

    try {
        std::cout << f.get() << "\n";
    } catch (const std::exception& e) {
        std::cout << e.what() << "\n";
    }
    return 0;
}
예제 #14
0
boost::shared_future<void> ocl_data_array::write(float* sourceArray, idx_t sourceBeginIndex, idx_t count, idx_t targetBeginIndex)
{
    verify_arg(sourceBeginIndex >= 0, "sourceBeginIndex");
    verify_arg(count > 0, "count");
    verify_arg(sourceArray != null, "sourceArray");
    verify_arg(targetBeginIndex >= 0, "targetBeginIndex");

    verify_if_accessible();

    auto& ctx = context();
    auto promise = new boost::promise<void>();
    auto future = boost::shared_future<void>(promise->get_future());
    try
    {
        cl::Event e;
        auto queue = ctx->cl_queue();

        queue.enqueueWriteBuffer(
            buffer(),
            false, // blocking
            targetBeginIndex * sizeof(float), // offset
            count * sizeof(float), // size
            sourceArray + sourceBeginIndex,
            nullptr,
            &e);

        e.setCallback(
        CL_COMPLETE,
        [](cl_event event, cl_int status, void* userData)
        {
            auto promise = (boost::promise<void>*)userData;
            try
            {
                if (status == CL_COMPLETE)
                {
                    // Done
                    promise->set_value();
                }
                else
                {
                    // cl::Error
                    promise->set_exception(std::make_exception_ptr(ocl_error(status, "Cannot read memory.")));
                }
            }
            catch (...)
            {
                promise->set_exception(std::current_exception());
            }
            delete promise;
        },
        promise);

        queue.flush();
    }
    catch (exception& ex)
    {
        delete promise;
        throw as_ocl_error(ex);
    }

    return future;
}
예제 #15
0
void semantics_multi(char* input, unsigned int in_size, char** output, unsigned int* out_size) {
    const rlim_t kStackSize = 64L * 1024L * 1024L; // min stack size = 64 Mb
    struct rlimit rl;
    int result;

    result = getrlimit(RLIMIT_STACK, &rl);
    if(result == 0) {
        if(rl.rlim_cur < kStackSize) {
            rl.rlim_cur = kStackSize;
            result = setrlimit(RLIMIT_STACK, &rl);
            if(result != 0) {
                fprintf(stderr, "setrlimit returned result = %d\n", result);
            }
        }
    }

    state_t state = gdsl_init();
    gdsl_set_code(state, input, in_size, 0);

    if(setjmp(*gdsl_err_tgt(state))) {
        snprintf(error_message, sizeof(error_message), "failure: %s", gdsl_get_error_message(state));
        set_exception();
        goto cleanup;
    }

    unsigned int size_increment = 100000;
    size_t reallocated_times = 0;
    size_t last_offset = 0;
    size_t out_max_size = 1000;

    *output = malloc(out_max_size);
    **output = '\0';
    *out_size = 1;

    while(last_offset < in_size) {
        obj_t rreil = gdsl_decode_translate_block(state, gdsl_config_default(state), gdsl_int_max(state));
        string_t fmt = gdsl_merge_rope(state, gdsl_rreil_pretty(state, rreil));

        while(strlen(fmt) > out_max_size - *out_size) {
            reallocated_times++;
            char* tmp = realloc(*output, out_max_size + size_increment);
            if(tmp == NULL) {
                snprintf(error_message, sizeof(error_message), "unable to resize output buffer: oldsize=%u,newsize = %u",
                    *out_size, (*out_size) + size_increment);
                set_exception();
                goto cleanup;
            }
            else {
                out_max_size = *out_size + size_increment;
                *output = tmp;
            }
        }

        *out_size = *out_size + strlen(fmt);
        strncat(*output, fmt, strlen(fmt));
        gdsl_reset_heap(state);
        last_offset = gdsl_get_ip(state);
    }

    cleanup:
    *out_size = *out_size - 1;
    gdsl_destroy(state);
}
예제 #16
0
 /* Poll the answer of the async function calls of the binding process.
 Returns NULL in case of error, Py_None for timeout, and the LDAPConnection
 object if successfully finished the binding. */
static PyObject *
binding(LDAPConnectIter *self) {
	int rc = -1;
	int err = 0;
	struct timeval polltime;
	LDAPControl **returned_ctrls = NULL;
	LDAPMessage *res;

	polltime.tv_sec = 0L;
	polltime.tv_usec = 10L;

	if (self->bind_inprogress == 0) {
		/* First call of bind. */
		rc = LDAP_bind(self->conn->ld, self->info, NULL, &(self->message_id));
		if (rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS) {
			set_exception(self->conn->ld, rc);
			return NULL;
		}
		self->bind_inprogress = 1;
		Py_RETURN_NONE;
	} else {
		if (self->async) {
			/* Binding is already in progress, poll result from the server. */
			rc = ldap_result(self->conn->ld, self->message_id, LDAP_MSG_ALL, &polltime, &res);
		} else {
			/* Block until the server response. */
			rc = ldap_result(self->conn->ld, self->message_id, LDAP_MSG_ALL, NULL, &res);
		}
		switch (rc) {
		case -1:
			/* Error occurred during the operation. */
			set_exception(self->conn->ld, 0);
			return NULL;
		case 0:
			/* Timeout exceeded.*/
			Py_RETURN_NONE;
		case LDAP_RES_BIND:
			/* Response is arrived from the server. */
			rc = ldap_parse_result(self->conn->ld, res, &err, NULL, NULL, NULL, &returned_ctrls, 0);

			if ((rc != LDAP_SUCCESS) ||
				(err != LDAP_SASL_BIND_IN_PROGRESS && err != LDAP_SUCCESS)) {
				/* Connection is failed. */
				set_exception(self->conn->ld, err);
				return NULL;
			}

			if (strcmp(self->info->mech, "SIMPLE") != 0) {
				/* Continue SASL binding procedure. */
				rc = LDAP_bind(self->conn->ld, self->info, res, &(self->message_id));

				if (rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS) {
					set_exception(self->conn->ld, rc);
					return NULL;
				}

				if (rc == LDAP_SASL_BIND_IN_PROGRESS) {
					Py_RETURN_NONE;
				}
			}

			if (rc == LDAP_SUCCESS) {
				/* The binding is successfully finished. */
				self->bind_inprogress = 0;
				self->conn->closed = 0;
				Py_INCREF((PyObject *)self->conn);
				return (PyObject *)self->conn;
			}
			Py_RETURN_NONE;
		default:
			/* Invalid return value, it never should happen. */
			PyErr_BadInternalCall();
			return NULL;
		}
	}
}
예제 #17
0
void BlockchainSynchronizer::actualizeFutureState() {
  std::unique_lock<std::mutex> lk(m_stateMutex);
  if (m_currentState == State::stopped && m_futureState == State::blockchainSync) { // start(), immideately attach observer
    m_node.addObserver(this);
  }

  if (m_futureState == State::stopped && m_currentState != State::stopped) { // stop(), immideately detach observer
    m_node.removeObserver(this);
  }

  while (!m_removeTransactionTasks.empty()) {
    auto& task = m_removeTransactionTasks.front();
    const Crypto::Hash& transactionHash = *task.first;
    auto detachedPromise = std::move(task.second);
    m_removeTransactionTasks.pop_front();

    try {
      doRemoveUnconfirmedTransaction(transactionHash);
      detachedPromise.set_value();
    } catch (...) {
      detachedPromise.set_exception(std::current_exception());
    }
  }

  while (!m_addTransactionTasks.empty()) {
    auto& task = m_addTransactionTasks.front();
    const ITransactionReader& transaction = *task.first;
    auto detachedPromise = std::move(task.second);
    m_addTransactionTasks.pop_front();

    try {
      auto ec = doAddUnconfirmedTransaction(transaction);
      detachedPromise.set_value(ec);
    } catch (...) {
      detachedPromise.set_exception(std::current_exception());
    }
  }

  m_currentState = m_futureState;
  switch (m_futureState) {
  case State::stopped:
    break;
  case State::blockchainSync:
    m_futureState = State::poolSync;
    lk.unlock();
    startBlockchainSync();
    break;
  case State::poolSync:
    m_futureState = State::idle;
    lk.unlock();
    startPoolSync();
    break;
  case State::idle:
    m_hasWork.wait(lk, [this] {
      return m_futureState != State::idle || !m_removeTransactionTasks.empty() || !m_addTransactionTasks.empty();
    });
    lk.unlock();
    break;
  default:
    break;
  }
}
예제 #18
0
파일: base_lco.cpp 프로젝트: 7ev3n/hpx
 void base_lco::set_exception_nonvirt (boost::exception_ptr const& e)
 {
     set_exception(e);
 }
예제 #19
0
/* Check on the initialisation thread and set cert policy. The `misc`
   parameter is never used (on Linux platform). The pointer of initialised
   LDAP struct is passed to the `ld` parameter. Return 1 if the initialisation
   thread is finished, 0 if it is still in progress, and -1 for error. */
int
_ldap_finish_init_thread(char async, XTHREAD thread, int *timeout, void *misc, LDAP **ld) {
    int rc = 0;
    ldapInitThreadData *val = (ldapInitThreadData *)misc;
    struct timespec ts;
    struct timeval now;
    struct timespec rest;
    int wait_msec = 100;
    long long nanosecs = 0;
    unsigned long long start_time, end_time;
    int retval = 0;

    /* Sanity check. */
    if (val == NULL) return -1;

    DEBUG("_ldap_finish_init_thread (async:%d, thread:%lu, timeout:%d, misc:%p)",
            async, thread, *timeout, misc);
    if (async || *timeout == -1) {
        wait_msec = 100;
    } else {
        wait_msec = *timeout;
    }

    /* Create absolute time. */
    rc = gettimeofday(&now, NULL);
    if (rc != 0) {
        PyErr_BadInternalCall();
        retval = -1;
        goto end;
    }
    ts.tv_sec = now.tv_sec;
    nanosecs = (now.tv_usec + 1000UL * wait_msec) * 1000UL;
    while (nanosecs >= 1000000000) {
        /* Nanosecs are over 1 second. */
        ts.tv_sec += 1;
        nanosecs -= 1000000000;
    }
    ts.tv_nsec = (long)nanosecs;

    /* Waiting on thread to release the lock. */
    rc = _pthread_mutex_timedlock(val->mux, &ts);

    switch (rc) {
    case ETIMEDOUT:
        if (async == 0 && *timeout != -1) {
            pthread_cancel(thread);
            set_exception(NULL, LDAP_TIMEOUT);
            free(val->ld);
            retval = -1;
            goto end;
        }
        return 0;
    case 0:
        if (val->flag == 0) {
            /* Premature locking, thread function is not finished. */
            pthread_mutex_unlock(val->mux);
            /* Set 5ms for sleeping time. */
            rest.tv_sec = 0;
            rest.tv_nsec = 5000000;
            /* Take a nap, try to avoid constantly locking from the main thread. */
            nanosleep(&rest, NULL);
            if (*timeout != -1) {
                *timeout -= 5;
                if (*timeout < 0) *timeout = 0;
            }
            return 0;
        }
        /* Block until thread is finished, but if it's async already
           waited enough on releasing the lock. */
        rc = pthread_join(thread, NULL);
        /* Thread is finished. */
        if (val->retval != LDAP_SUCCESS) {
#ifdef HAVE_KRB5
            if (val->info->errmsg != NULL) {
                PyObject *error = get_error_by_code(0x31);
                if (error == NULL) goto end;
                PyErr_SetString(error, val->info->errmsg);
                Py_DECREF(error);
            } else {
                set_exception(NULL, val->retval);
            }
#else
            set_exception(NULL, val->retval);
#endif
            free(val->ld);
            retval = -1;
            goto end;
        }
        if (*timeout != -1) {
            /* Calculate passed time in milliseconds. */
            start_time = (unsigned long long)(now.tv_sec) * 1000
                    + (unsigned long long)(now.tv_usec) / 1000;

            gettimeofday(&now, NULL);
            end_time = (unsigned long long)(now.tv_sec) * 1000
                            + (unsigned long long)(now.tv_usec) / 1000;
            /* Deduct the passed time from the overall timeout. */
            *timeout -= (end_time - start_time);
            if (*timeout < 0) *timeout = 0;
        }
        /* Set initialised LDAP struct pointer. */
        *ld = val->ld;
        retval = 1;
        goto end;
    default:
        /* The thread is failed. */
        PyErr_BadInternalCall();
        retval = -1;
        goto end;
    }
end:
    /* Clean-up. */
    free(val->url);
    pthread_mutex_destroy(val->mux);
    free(val->mux);
    free(val);
    return retval;
}
예제 #20
0
 void set(std::exception_ptr exc)
 {
     set_exception(exc);
 }
예제 #21
0
/* Finish the initialisation by checking the result of the separate thread for TLS.
   The `misc` parameter is a pointer to the thread's  data structure that contains the
   LDAP struct. The initialised LDAP struct is passed to the `ld` parameter. */
int
_ldap_finish_init_thread(char async, XTHREAD thread, int *timeout, void *misc, LDAP **ld) {
    int rc = -1;
    int retval = 0;
    SYSTEMTIME st;
    FILETIME ft;
    ULONGLONG start_time;
    ULONGLONG end_time;
    ldapInitThreadData *val = (ldapInitThreadData *)misc;

    GetSystemTime(&st);
    SystemTimeToFileTime(&st, &ft);
    /* Current time in 100-nanosec. */
    start_time = (((ULONGLONG)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;

    /* Sanity check. */
    if (val == NULL || thread == NULL) return -1;

    DEBUG("_ldap_finish_init_thread (async:%d, thread:%p, timeout:%d, misc:%p)",
        async, thread, *timeout, misc);
    if (async) {
        rc = WaitForSingleObject(thread, 10);
    } else {
        rc = WaitForSingleObject(thread, *timeout);
    }

    switch (rc) {
    case WAIT_TIMEOUT:
        if (async == 0) {
            TerminateThread(thread, -1);
            CloseHandle(thread);
            set_exception(NULL, LDAP_TIMEOUT);
            retval = -1;
            goto end;
        }
        return 0;
    case WAIT_OBJECT_0:
        if (async == 0 && *timeout != -1) {
            GetSystemTime(&st);
            SystemTimeToFileTime(&st, &ft);
            /* Current time in 100-nanosec. */
            end_time = (((ULONGLONG)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
            /* Deduct the passed time from the overall timeout. */
            *timeout -= (int)((end_time - start_time) / 10000);
            if (*timeout < 0) *timeout = 0;
        }
        if (val->retval != LDAP_SUCCESS) {
            /* The ldap_connect is failed. Set a Python error. */
            set_exception(NULL, val->retval);
            retval = -1;
            goto end;
        }
        /* Set the new LDAP struct. */
        *ld = val->ld;
        retval = 1;
        goto end;
    default:
        /* The thread is failed. */
        PyErr_BadInternalCall();
        retval = -1;
        goto end;
    }
end:
    /* Clean up the mess. */
    CloseHandle(thread);
    free(val->url);
    free(val);
    return retval;
}
예제 #22
0
void native_server_impl::start()
{
    BONEFISH_TRACE("starting native server");
    assert(!m_connector);
    m_connector = std::make_shared<native_connector>();

    std::weak_ptr<native_server_impl> weak_this = shared_from_this();

    auto connect_handler = [this, weak_this](
            const std::shared_ptr<native_endpoint>& component_endpoint) {
        auto connected = std::make_shared<native_endpoint_promise>();

        auto shared_this = weak_this.lock();
        if (!shared_this) {
            connected->set_exception(boost::copy_exception(std::runtime_error("connect failed")));
            return connected->get_future();
        }

        m_io_service.post([this, weak_this, connected, component_endpoint] () {
            auto shared_this = weak_this.lock();
            if (!shared_this) {
                connected->set_exception(boost::copy_exception(std::runtime_error("server shutdown")));
                return;
            }

            try {
                auto server_endpoint = on_connect(component_endpoint);
                connected->set_value(server_endpoint);
            } catch (...) {
                connected->set_exception(boost::current_exception());
            }
        });

        return connected->get_future();
    };
    m_connector->set_connect_handler(connect_handler);

    auto disconnect_handler = [this, weak_this](
            const std::shared_ptr<native_endpoint>& server_endpoint) {
        auto disconnected = std::make_shared<boost::promise<void>>();

        auto shared_this = weak_this.lock();
        if (shared_this) {
            disconnected->set_exception(boost::copy_exception( std::runtime_error("disconnect failed")));
            return disconnected->get_future();
        }

        m_io_service.post([this, weak_this, disconnected, server_endpoint] () {
            auto shared_this = weak_this.lock();
            if (!shared_this) {
                disconnected->set_exception(boost::copy_exception(std::runtime_error("server shutdown")));
                return;
            }

            try {
                on_disconnect(server_endpoint);
                disconnected->set_value();
            } catch (...) {
                disconnected->set_exception(boost::current_exception());
            }
        });

        return disconnected->get_future();
    };
    m_connector->set_disconnect_handler(disconnect_handler);
}