コード例 #1
0
ファイル: List.c プロジェクト: fedorms/craftd
CDList*
CD_CloneList (CDList* self)
{
    CDList* cloned = CD_CreateList();

    assert(self);

    CD_LIST_FOREACH(self, it) {
        CD_ListPush(cloned, CD_ListIteratorValue(it));
    }
コード例 #2
0
ファイル: Workers.c プロジェクト: Youx/craftd
void
CD_AddJob (CDWorkers* self, CDJob* job)
{
    pthread_mutex_lock(&self->lock.mutex);

    CD_ListPush(self->jobs, (CDPointer) job);

    pthread_cond_signal(&self->lock.condition);

    pthread_mutex_unlock(&self->lock.mutex);
}
コード例 #3
0
ファイル: Event.c プロジェクト: CogDis/craftd
CDList*
CD_CreateEventParameters (const char* first, ...)
{
	va_list ap;
	CDList* self    = CD_CreateList();
	char*   current = NULL;

	if (first) {
		va_start(ap, first);

		CD_ListPush(self, (CDPointer) strdup(first));

		while ((current = va_arg(ap, char*))) {
			CD_ListPush(self, (CDPointer) strdup(current));
		}

		va_end(ap);
	}

	return self;
}
コード例 #4
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;
}