Пример #1
0
    bool OperationQueue::Impl::cancel(const std::function<bool(const Record::Ptr&)>& fun)
    {
        if (cancelQueue(_inputs, _inputMutex, fun))
        {
            return true;
        }

        if (cancelQueue(_outputs, _outputMutex, fun))
        {
            return true;
        }

        return false;
    }
Пример #2
0
void ChannelPoolChannel::cancelRead()
{
    const int NUM_ENTRIES = 16;
    const int SIZE        = NUM_ENTRIES * sizeof(ReadQueueEntry);

    char                               BUFFER[SIZE];
    bdlma::BufferedSequentialAllocator bufferAllocator(BUFFER, SIZE);

    ReadQueue cancelQueue(&bufferAllocator);

    {
        bslmt::LockGuard<bslmt::Mutex> lock(&d_mutex);

        if (!d_readQueue.size()) {
            return;                                                   // RETURN
        }

        ReadQueue::iterator it = d_readQueue.begin();

        if (d_callbackInProgress) {
            it->d_progress = AsyncChannel::e_CANCELED;
            ++it;
        }

        if (!d_closed) {
            cancelQueue.insert(cancelQueue.end(), it, d_readQueue.end());
        }

        for (ReadQueue::iterator it2 = it; it2 != d_readQueue.end(); ++it2) {
            if (bsls::TimeInterval(0) != it2->d_timeOut) {
                d_channelPool_p->deregisterClock(it2->d_timeOutTimerId);
            }
        }

        d_readQueue.erase(it, d_readQueue.end());
    }

    if (!d_closed) {
        // We do not invoke callbacks on a closed channel, because to be
        // correct those callbacks should only be involved in the dispatcher
        // thread of the channel pool's manager corresponding to this channel,
        // but this object might be being destroyed and no further callbacks
        // referencing this channel should be invoked.

        bsls::TimeInterval now = bdlt::CurrentTime::now();
        int dummy = 0;
        btlb::Blob dummyBlob;
        for (ReadQueue::iterator it = cancelQueue.begin();
             it != cancelQueue.end(); ++it) {
            bsl::function<void()> cancelNotifyCallback(
                                 bdlf::BindUtil::bind(it->d_readCallback,
                                                      AsyncChannel::e_CANCELED,
                                                      &dummy,
                                                      &dummyBlob,
                                                      d_channelId));

            int rc;
            while (1 == (rc = d_channelPool_p->registerClock(
                                                        cancelNotifyCallback,
                                                        now,
                                                        bsls::TimeInterval(0),
                                                        ++d_nextClockId,
                                                        d_channelId))) {
                d_nextClockId += 0x01000000;
            }

            if (rc) {
                // The channel was already cleaned up in channel pool because
                // the connection was closed at the other end.  We assume that
                // this is the event manager's dispatcher thread and it is safe
                // to invoke the cancel notify callback from this thread.

                cancelNotifyCallback();
            }
        }
    }
}