OSDN Git Service

initial files
[iptd/iPTd_R3.git] / src / ry0 / iPTd / CommandRunner.cpp
1 //
2 //
3 //
4
5 #define DBG_LEVEL 3
6 #include "Raym/Log.h"
7
8 #include <process.h>
9
10 #include "CommandRunner.h"
11
12 using namespace Raym;
13
14 namespace ry0
15 {
16 namespace iPTd
17 {
18
19 CommandRunner::CommandRunner()
20 {
21     DebugLog2("CommandRunner::CommandRunner()");
22
23     _state     = ST_IDLE;
24     _command   = NULL;
25     _arguments = NULL;
26 }
27
28 CommandRunner::~CommandRunner()
29 {
30     stop();
31
32     RELEASE(_command);
33     RELEASE(_arguments);
34
35     DebugLog2("CommandRunner::~CommandRunner()");
36 }
37
38 CommandRunner *CommandRunner::alloc()
39 {
40     return new CommandRunner();
41 }
42
43 CommandRunner *CommandRunner::init()
44 {
45     DebugLog2("CommandRunner::init()");
46
47     _state = ST_IDLE;
48
49     return this;
50 }
51
52 CommandRunner *CommandRunner::retain()
53 {
54     DebugLog2("CommandRunner::retain()");
55
56     Object::retain();
57     return this;
58 }
59
60 CommandRunner *CommandRunner::autorelease()
61 {
62     DebugLog2("CommandRunner::autorelease()");
63
64     Object::autorelease();
65     return this;
66 }
67
68 void CommandRunner::setCommandPath(String *path)
69 {
70     DebugLog2("CommandRunner::setCommandPath()");
71
72     RELEASE(_command);
73     if (path != NULL)
74     {
75         _command = path->retain();
76     }
77 }
78
79 void CommandRunner::setArguments(Array *args)
80 {
81     DebugLog2("CommandRunner::setArguments()");
82
83     RELEASE(_arguments);
84     if (args != NULL)
85     {
86         _arguments = args->retain();
87     }
88 }
89
90 bool CommandRunner::readLine(String *line)
91 {
92     return false;
93 }
94
95 void CommandRunner::write(String *line)
96 {
97 }
98
99 unsigned __stdcall CommandRunner_run(void *arg)
100 {
101     ((CommandRunner *)arg)->run();
102     return 0;
103 }
104
105 void CommandRunner::run()
106 {
107     DebugLog2("CommandRunner::run()");
108
109     AutoreleasePool *pool = AutoreleasePool::alloc()->init();
110
111     // lock
112     RaymLock(this);
113
114     while ((_command != NULL) && (_state == ST_READY))
115     {
116         DebugLog3("pre processing");
117
118         // パイプ生成
119         Pipe *pipe = Pipe::alloc()->init();
120
121         // タスク生成
122         Task *task = Task::alloc()->init();
123         task->setLaunchPath(_command);
124
125         // 引数設定
126         if (_arguments != NULL)
127         {
128             task->setArguments(_arguments);
129         }
130
131         // 標準出力設定
132         task->setStandardOutput(pipe->fileHandleForWriting());
133         task->setStandardError(pipe->fileHandleForWriting());
134
135         // タスク実行
136         task->launch();
137
138         // 読み込み
139         FileInputStream *fis = FileInputStream::fileInputStream(pipe->fileHandleForReading());
140
141         // 状態変更
142         _state = ST_RUN;
143
144         // unlock
145         RaymUnlock(this);
146
147         bool done = false;
148         while (!done)
149         {
150             // ループ処理
151             AutoreleasePool *pool2 = AutoreleasePool::alloc()->init();
152
153             // 1行読み込み
154             bool done2 = readLine(fis->readLine());
155
156             // lock
157             RaymLock(this);
158
159             // 終了チェック
160             done = (done2 || (_state == ST_DONE));
161
162             // unlock
163             RaymUnlock(this);
164
165             pool2->release();
166         }
167
168         DebugLog3("post processing");
169
170         // タスク終了
171         task->terminate();
172         task->release();
173
174         // パイプ破棄
175         pipe->release();
176
177         // lock
178         RaymLock(this);
179         break;
180     }
181
182     // 状態変更
183     _state = ST_IDLE;
184
185     // unlock
186     RaymUnlock(this);
187
188     pool->release();
189
190     DebugLog2("CommandRunner::run() done.");
191 }
192
193 bool CommandRunner::start()
194 {
195     DebugLog2("CommandRunner::start()");
196     
197     bool result = false;
198     
199     RaymLock(this);
200     
201     if (_state == ST_IDLE)
202     {
203         HANDLE h;
204         unsigned int uiThreadId;
205         
206         h = (HANDLE)_beginthreadex(NULL, 0, CommandRunner_run, this, 0, &uiThreadId);
207         if (h != NULL)
208         {
209             _state = ST_READY;
210
211             RaymUnlock(this);
212
213             bool done = false;
214             while (!done)
215             {
216                 bool needSleep = false;
217
218                 RaymLock(this);
219
220                 if (_state == ST_IDLE)
221                 {
222                     done = true;
223                 }
224                 else if (_state == ST_RUN)
225                 {
226                     done = true;
227                     result = true;
228                 }
229                 else if (_state == ST_READY)
230                 {
231                     needSleep = true;
232                 }
233                 RaymUnlock(this);
234
235                 if (needSleep)
236                 {
237                     ::Sleep(100); // 100 ms
238                 }
239             }
240
241             RaymLock(this);
242         }
243     }
244
245     RaymUnlock(this);
246
247     return result;
248 }
249
250 void CommandRunner::stop()
251 {
252     DebugLog2("CommandRunner::stop()");
253     RaymLock(this);
254     if (_state != ST_IDLE)
255     {
256         _state = ST_DONE;
257     }
258     RaymUnlock(this);
259     bool done = false;
260     while (!done)
261     {
262         RaymLock(this);
263         done = (_state == ST_IDLE);
264         RaymUnlock(this);
265         if (!done)
266         {
267             ::Sleep(100);
268         }
269     }
270     DebugLog2("CommandRunner::stop() done.");
271 }
272
273 bool CommandRunner::isRunning()
274 {
275     bool result;
276     RaymLock(this);
277     result = (_state == ST_RUN);
278     RaymUnlock(this);
279     return result;
280 }
281
282 const char *CommandRunner::className()
283 {
284     return "CommandRunner";
285 }
286
287 } // iPTd
288 } // ry0