コード例 #1
0
ファイル: Buffer.c プロジェクト: gmoonen/craftd
CDPointer
CD_BufferContent (CDBuffer* self)
{
    CDPointer data = (CDPointer) CD_malloc(CD_BufferLength(self));

    evbuffer_copyout(self->raw, (void*) data, CD_BufferLength(self));

    return data;
}
コード例 #2
0
ファイル: Buffer.c プロジェクト: gmoonen/craftd
void
CD_BufferAddBuffer (CDBuffer* self, CDBuffer* data)
{
    CDPointer stuff = CD_BufferContent(data);

    evbuffer_add(self->raw, (void*) stuff, CD_BufferLength(data));

    CD_free((void*) stuff);
}
コード例 #3
0
ファイル: Buffer.c プロジェクト: gmoonen/craftd
CDBuffer*
CD_BufferRemoveBuffer (CDBuffer* self)
{
    struct evbuffer* buffer = evbuffer_new();
    CDBuffer*        result;

    evbuffer_remove_buffer(self->raw, buffer, CD_BufferLength(self));

    result = CD_WrapBuffer(buffer);

    result->external = false;

    return result;
}
コード例 #4
0
ファイル: Buffer.c プロジェクト: gmoonen/craftd
bool
CD_BufferEmpty (CDBuffer* self)
{
    return CD_BufferLength(self) == 0;
}
コード例 #5
0
ファイル: Worker.c プロジェクト: Youx/craftd
bool
CD_RunWorker (CDWorker* self)
{
    assert(self);

    SLOG(self->server, LOG_INFO, "worker %d started", self->id);

    while (self->working) {
        self->job = NULL;

        if (!CD_HasJobs(self->workers)) {
            pthread_mutex_lock(&self->workers->lock.mutex);

            SDEBUG(self->server, "worker %d ready", self->id);

            pthread_cond_wait(&self->workers->lock.condition, &self->workers->lock.mutex);

            pthread_mutex_unlock(&self->workers->lock.mutex);
        }

        if (!self->working) {
            break;
        }

        self->job = CD_NextJob(self->workers);

        if (!self->job) {
            SDEBUG(self->server, "no jobs for %d :<", self->id);
            continue;
        }

        SDEBUG(self->server, "worker %d running", self->id);

        if (self->job->type == CDCustomJob) {
            CDCustomJobData* data = (CDCustomJobData*) self->job->data;

            data->callback(data->data);

            CD_DestroyJob(self->job);
        }
        else if (CD_JOB_IS_PLAYER(self->job)) {
            CDClient* client;

            if (self->job->type == CDClientProcessJob) {
                client = ((CDClientProcessJobData*) self->job->data)->client;
            }
            else {
                client = (CDClient*) self->job->data;
            }

            if (!client) {
                CD_DestroyJob(self->job);
                continue;
            }

            pthread_rwlock_rdlock(&client->lock.status);
            if (client->status == CDClientDisconnect) {
                if (self->job->type != CDClientDisconnectJob) {
                    CD_DestroyJob(self->job);
                    self->job = NULL;
                    client->jobs--;
                }
            }
            pthread_rwlock_unlock(&client->lock.status);

            if (!self->job) {
                continue;
            }

            if (self->job->type == CDClientConnectJob) {
                CD_EventDispatch(self->server, "Client.connect", client);

                pthread_rwlock_wrlock(&client->lock.status);
                if (client->status != CDClientDisconnect) {
                    client->status = CDClientIdle;
                }
                pthread_rwlock_unlock(&client->lock.status);

                CD_DestroyJob(self->job);

                if (CD_BufferLength(client->buffers->input) > 0) {
                    CD_ReadFromClient(client);
                }
            }
            else if (self->job->type == CDClientProcessJob) {
                CD_EventDispatch(self->server, "Client.process", client,
                    ((CDClientProcessJobData*) self->job->data)->packet);

                CD_EventDispatch(self->server, "Client.processed", client,
                    ((CDClientProcessJobData*) self->job->data)->packet);

                pthread_rwlock_wrlock(&client->lock.status);
                if (client->status != CDClientDisconnect) {
                    client->status = CDClientIdle;
                }

                client->jobs--;
                pthread_rwlock_unlock(&client->lock.status);

                CD_DestroyJob(self->job);

                if (CD_BufferLength(client->buffers->input) > 0) {
                    CD_ReadFromClient(client);
                }
            }
            else if (self->job->type == CDClientDisconnectJob) {
                while (true) {
                    pthread_rwlock_rdlock(&client->lock.status);

                    if (client->jobs < 1) {
                        pthread_rwlock_unlock(&client->lock.status);
                        break;
                    }

                    pthread_rwlock_unlock(&client->lock.status);
                }

                CD_EventDispatch(self->server, "Client.disconnect", client, (bool) ERROR(client));

                CD_ListPush(self->server->disconnecting, (CDPointer) client);

                CD_ServerFlush(client->server, false);

                CD_DestroyJob(self->job);
            }
        }

        self->job = NULL;
    }

    return true;
}