summaryrefslogtreecommitdiff
path: root/includes/TaskMan.h
blob: 088d5d713aa572b97557d646c6d5a7dfc7e26607 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#pragma once

#include <stdint.h>
#ifndef _WIN32
#include <coro.h>
#endif
#include <ev++.h>
#include <ext/hash_set>
#include <queue>
#include <Threads.h>
#include <Exceptions.h>
#include <Task.h>

namespace gnu = __gnu_cxx;

namespace Balau {

class TaskScheduler;

namespace Events {

class Async;

};

class TaskMan {
  public:
      TaskMan();
      ~TaskMan();
    int mainLoop();
    static TaskMan * getDefaultTaskMan();
    struct ev_loop * getLoop() { return m_loop; }
    void signalTask(Task * t);
    static void stop(int code);
    void stopMe(int code) { m_stopped = true; m_stopCode = code; }
    static Thread * createThreadedTaskMan();
    bool stopped() { return m_stopped; }
    template<class T>
    static T * createTask(T * t, Task * stick = NULL) { TaskMan::registerTask(t, stick); return t; }

  private:
    static void registerTask(Task * t, Task * stick);
    void * getStack();
    void freeStack(void * stack);
    void addToPending(Task * t);
#ifndef _WIN32
    coro_context m_returnContext;
#else
    void * m_fiber;
#endif
    friend class Task;
    friend class TaskScheduler;
    template<class T>
    friend T * createTask(T * t, Task * stick = NULL);
    struct taskHasher { size_t operator()(const Task * t) const { return reinterpret_cast<uintptr_t>(t); } };
    typedef gnu::hash_set<Task *, taskHasher> taskHash_t;
    taskHash_t m_tasks, m_signaledTasks;
    Queue<Task> m_pendingAdd;
    bool m_stopped;
    struct ev_loop * m_loop;
    bool m_allowedToSignal;
    ev::async m_evt;
    std::queue<void *> m_stacks;
    int m_nStacks;
    int m_stopCode;
};

};