Beispiel #1
0
	virtual void startup() {
		thread_accepter_.start(new _ESQ accepter(setter_, dispatcher_, handler_), this);
		thread_transceiver_.start(new _ESQ transceiver(setter_, dispatcher_, handler_), this);
		thread_recycler_.start(new _ESQ recycler(setter_, dispatcher_, handler_), this);
		thread_destroyer_.start(new _ESQ destroyer(setter_, dispatcher_, handler_), this);
		processer_pools_.start(this);
	}
Beispiel #2
0
int ngrest_server_dispatch(ngrest_server_request* request, ngrest_mod_callbacks callbacks)
{
    try {
        ngrest::MessageContext context;

        context.pool = pooler.obtain();
        PoolRecycler recycler(context.pool);

        context.engine = &engine;
        context.transport = &transport;
        context.request = context.pool->alloc<ngrest::HttpRequest>();
        context.response = context.pool->alloc<ngrest::HttpResponse>();
        context.response->poolBody = pooler.obtain(65536); // 64 KB chunks for output buffer

        ngrest::HttpRequest* httpRequest = static_cast<ngrest::HttpRequest*>(context.request);
        ngrest::HttpResponse* httpResponse = static_cast<ngrest::HttpResponse*>(context.response);

        ModMessageCallback messageCallback(httpResponse);
        context.callback = &messageCallback;

        httpRequest->setMethod(request->method);
        httpRequest->path = request->uri;
        httpRequest->clientHost = request->clientHost;
        httpRequest->clientPort = request->clientPort;

        HeaderIterateContext itCtx = {
            httpRequest,
            nullptr,
            &context
        };

        callbacks.iterate_request_headers(request->req, &itCtx, [](void* context, const char* name, const char* value) {
            HeaderIterateContext* itCtx = reinterpret_cast<HeaderIterateContext*>(context);
            ngrest::Header* header = itCtx->context->pool->alloc<ngrest::Header>();

            char* headerName = itCtx->context->pool->putCString(name, true);
            toLowerCase(headerName);

            header->name = headerName;
            header->value = value;
            if (itCtx->lastHeader == nullptr) {
                itCtx->httpRequest->headers = header;
            } else {
                itCtx->lastHeader->next = header;
            }
            itCtx->lastHeader = header;
            return 1;
        });

        if (request->hasBody) {
            ngrest::MemPool* poolRequest = pooler.obtain(65536);
            PoolRecycler recycler(poolRequest);
            if (request->bodySize > 0)
                poolRequest->reserve(request->bodySize + 1); // '\0'

            const int64_t chunkSize = poolRequest->getChunkSize();
            int64_t bufferSize = chunkSize;
            int64_t read = 0;
            int64_t total = 0;
            char* buffer = poolRequest->grow(chunkSize);
            for (;;) {
                read = callbacks.read_block(request->req, buffer, bufferSize);
                if (read < 0) {
                    callbacks.write_block(request->req, "Failed to read block!", 21);
                    return 500;
                }

                if (!request->bodySize && !read) // eof while body size unknown. stopping read
                    break;

                buffer += read;
                bufferSize -= read;
                if (bufferSize == 0) {
                    buffer = poolRequest->grow(chunkSize);
                    bufferSize = chunkSize;
                }
                total += read;

                if (request->bodySize && total >= request->bodySize)
                    break;  // according to request->bodySize the whole request is read
            }

            poolRequest->shrinkLastChunk(bufferSize);

            ngrest::MemPool::Chunk* body = poolRequest->flatten();
            context.request->body = body->buffer;
            context.request->bodySize = body->size;

            engine.dispatchMessage(&context); // poolRequest will be recycled ouside this scope
        } else {
            engine.dispatchMessage(&context);
        }

        for (const ngrest::Header* header = httpResponse->headers; header; header = header->next) {
            if (!strcmp(header->name, "Content-Type")) {
                callbacks.set_content_type(request->req, header->value);
            } else {
                callbacks.set_response_header(request->req, header->name, header->value);
            }
        }

        ngrest_server_write_response(request, callbacks, httpResponse->poolBody);

        callbacks.finalize_response(request->req, httpResponse->statusCode);

        return 0;
    } catch (const std::exception& e) {
        const char* error = e.what();
        ngrest::LogWarning() << error;
        callbacks.write_block(request->req, error, strlen(error));
    } catch (...) {
        ngrest::LogWarning() << "Unknown exception raised";
        callbacks.write_block(request->req, "Internal server error", 22);
    }

    return 500;
}
Beispiel #3
0
void Output::run()
{
    mutex()->lock ();
    if (!bytes_per_millisecond_)
    {
        qWarning("Output: invalid audio parameters");
        mutex()->unlock ();
        return;
    }
    mutex()->unlock ();

    bool done = false;
    Buffer *b = 0;
    qint64 l, m = 0;

    dispatch(PlayerUtils::Playing);

    while (!done)
    {
        mutex()->lock();
        recycler()->mutex()->lock();
        done = user_stop_;

        while (!done && (recycler()->empty() || pause_))
        {
            mutex()->unlock();
            recycler()->cond()->wakeOne();
            recycler()->cond()->wait(recycler()->mutex());
            mutex()->lock ();
            done = user_stop_;
        }
        status();
        if (!b)
        {
            b = recycler()->next();
            if (b && b->rate)
            {
                kbps_ = b->rate;
            }
        }
        recycler()->cond()->wakeOne();
        recycler()->mutex()->unlock();
        mutex()->unlock();
        if (b)
        {
            changeVolume(b->data, b->nbytes, channels_);
            l = 0;
            m = 0;

            if (is_seeking_)
            {
                enable(b->seeking_finished);
                is_seeking_ = !b->seeking_finished;
            }

            while (l < b->nbytes)
            {
                m = writeAudio(b->data + l, b->nbytes - l);
                if(m >= 0)
                {
                    total_written_ += m;
                    l+= m;
                }
                else
                {
                    break;
                }
            }
            if(m < 0)
            {
                break;
            }
        }
        mutex()->lock();
        //force buffer change
        recycler()->mutex()->lock ();
        recycler()->done();
        recycler()->mutex()->unlock();
        b = 0;
        mutex()->unlock();
    }
    mutex()->lock ();
    //write remaining data
    if(finish_)
    {
        flush();
        qDebug("Output: total written %lld", total_written_);
    }
    dispatch(PlayerUtils::Stopped);
    mutex()->unlock();
}