aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Thread/Thread.h
blob: e271fc9bd8456cae9dd9bcbe4da72e9867c94299 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef __JIN_THREAD_H
#define __JIN_THREAD_H
#include "../modules.h"
#if JIN_MODULES_THREAD

#include <string>
#include <map>
#if JIN_THREAD_SDL 
#   include "SDL2/SDL_thread.h"
#elif JIN_THREAD_CPP 
#   include <thread>
#   include <mutex>
#   include <condition_variable>
#endif

namespace jin
{
namespace thread
{
    /*
    * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ
    * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ
    * ָһԹԴзʵĴ룬һֻƻ㷨һ򡢽̡߳̿ӵжٽ򣬵Dz
    * һӦûҪ˻ƵԴУꡢСжϴڶеĴ
    * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ
    * ߣ߻ָѣ
    */
    class Mutex;
    class Conditional;

    /*
    * Thread:demand	    Receive a message from a thread. Wait for the message to exist before returning.	
    * Thread:getName    Get the name of a thread.	
    * Thread:kill	    Forcefully terminate the thread.	
    * Thread:peek	    Receive a message from a thread, but leave it in the message box.	
    * Thread:receive    Receive a message from a thread.	
    * Thread:send	    Send a message.	
    * Thread:set	    Set a value.	
    * Thread:start	    Starts the thread.	
    * Thread:wait	    Wait for a thread to finish.	
    */
    class Thread
    {
    public:
        union Value
        {
            enum
            {
                INTEGER, 
                REAL, 
                BOOL, 
                STRING,
                POINTER
            } type;

            int integer;
            float real;
            bool boolean;
            const char* cstring;
            void* pointer;

            Value() {};
            Value(int i) : integer(i), type(INTEGER){};
            Value(float r) : real(r), type(REAL) {};
            Value(bool b) : boolean(b), type(BOOL) {};
            Value(const char* cstr) : cstring(cstr), type(STRING) {};
            Value(void* p) : pointer(p), type(POINTER) {};
        };

    private:
        class ThreadData
        {
        public:
            ThreadData(Mutex*, Conditional*);
            ~ThreadData();
            bool exist(const std::string& name);
            void set(std::string name, Value value);
            Value get(std::string name);
            void remove(std::string name);
            Conditional* condition;
            Mutex* mutex;

        private:
            std::map<std::string, Value> share; // threads shared value
        };

    public:
        typedef int(ThreadRunner)(void* /*ThreadData*/);
        Thread(const std::string name, ThreadRunner threadfuncs);
        ~Thread();
        bool start();
        void wait();
        void send(std::string name, Value value);
        bool receive(std::string name);
        Value fetch(std::string name);
        Value demand(std::string name);
        const char* getName();
        bool isRunning();
        //void kill();
        //Value peek();

    private:
        void lock();
        void unlock();
    #if JIN_THREAD_SDL 
        SDL_Thread* handle;         // SDL thread
    #elif JIN_THREAD_CPP 
        std::thread* handle;        // cpp thread
    #endif
        Mutex* mutex;               // mutex variable
        Conditional* condition;     // condition variable
        ThreadRunner* threadRunner; // thread function 
        ThreadData* common;         // threads common data
        const std::string name;     // thread name 
        bool running;               // running

    };

} // thread
} // jin

#endif // JIN_MODULES_THREAD
#endif // __JIN_THREAD_H