вопрос обратного вызова - PullRequest
1 голос
/ 19 февраля 2011

По сути, я пытаюсь сделать диспетчер, но это не удается, потому что это всегда "! Event-> callback_function", мой код:

#include "event.h"
#include "memory.h"
#include "thread.h"

#include <stdio.h>
#include <time.h>
#include <assert.h>

bool running;

typedef struct Event {
    event_callback_t cb;
    time_t delay;
    void* p;
    struct Event* next;
} Event;

Event* g_events;

void _remove_event           __P((Event**, Event *));
void event_dispatch_internal        __P(());
void add_event_internal             __P((Event**, Event *));

void
event_dispatch()
{
    g_events = (Event *)MyMalloc(sizeof(*g_events));
    create_thread((callback_t)event_dispatch_internal, (void *)NULL);
}

void
add_event_internal(Event** events, Event* event)
{
    event->next = *events;
    *events = event;
}

void
add_event(callback, param, delay)
    event_callback_t callback;
    void *param;
    time_t delay;
{
    Event* event;
    event = (Event *)MyMalloc(sizeof(*event));
    assert(0 != event);

    event->delay = time(NULL) + delay;
    event->p = param;
    event->cb = callback;
    add_event_internal(&g_events, event);
}

void
_remove_event(Event** events, Event* event)
{
    event = *events;
    *events = event->next;
}

void
event_dispatch_internal()
{
#ifdef _DEBUG
    fprintf(stderr, "Events started\n");
#endif
    while (true) {
        Event* tmp;
        for (tmp = g_events; tmp; tmp = tmp->next) {
            if (time(NULL) >= tmp->delay) {
                tmp->cb(tmp->p);
#ifdef _DEBUG
                fprintf(stderr, "Executed event %p:%u\n", (void *)tmp, (unsigned int)tmp->delay);
#endif
                _remove_event(&g_events, tmp);
            }
        }
    }
}

, он вылетает, но когда я делаю это так:

            for (tmp = g_events; tmp; tmp = tmp->next) {
            if (time(NULL) >= tmp->delay) {
                if (!tmp->cb) {
                    tmp->cb(tmp->p);
#ifdef _DEBUG
                    fprintf(stderr, "Executed event %p:%u\n", (void *)tmp, (unsigned int)tmp->delay);
#endif
                } else {
                    fprintf(stderr, "Couldnt execute event %p:%u\n", (void *)tmp, (unsigned int)tmp->delay);
                }
            }
        }

всегда выдает «Не удалось выполнить событие blabla»

, а я так его называю:

void test_(void *);

void
test_(void *p)
{
    fprintf(stderr, "test(): %d\n", *(int *)p);
}

int main()
{
    int test;
    test = 5;
    event_dispatch();
    add_event(test_, (void *)&test, 1);
    do { } while (1);
    return 0;
}

любая помощь оказывается

1 Ответ

3 голосов
/ 19 февраля 2011

Ваш код не имеет смысла . Вы запускаете поток, который затем зацикливается, пытаясь обойти список g_events. Однако при запуске, в котором есть только один неинициализированный узел, так что может произойти все что угодно!

Кроме того (1) у вас нет синхронизации между потоками, поэтому даже если вы решите вышеуказанную проблему, вы, скорее всего, столкнетесь с опасными расами, когда люди попытаются добавить события.

Кроме того (2), оба ваших потока фактически находятся в циклах "занят-ожидание", которые высосут ваш процессор. Вам нужно исследовать механизм, который заставляет ваши потоки спать, пока что-то не приходит, например семафоры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...