where : value returned was inverted.
[scilab.git] / scilab / modules / core / src / cpp / runner.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "runner.hxx"
14
15 __threadLock Runner::m_lock;
16 __threadSignal Runner::m_awakeScilab;
17 __threadSignalLock Runner::m_awakeScilabLock;
18
19 void Runner::init()
20 {
21     __InitSignal(&m_awakeScilab);
22     __InitSignalLock(&m_awakeScilabLock);
23 }
24
25 void *Runner::launch(void *args)
26 {
27     bool bdoUnlock = false;
28     //try to lock locker ( waiting parent thread register me )
29     __Lock(&m_lock);
30     //just release locker
31     __UnLock(&m_lock);
32
33     //exec !
34     Runner *me = (Runner *)args;
35     try
36     {
37         me->getProgram()->accept(*(me->getVisitor()));
38         //ConfigVariable::clearLastError();
39     }
40     catch (ScilabException se)
41     {
42         // remove the last call from where in case pause/abort
43         ConfigVariable::where_end();
44         scilabErrorW(se.GetErrorMessage().c_str());
45     }
46
47     __threadKey currentThreadKey = __GetCurrentThreadKey();
48
49     //change thread status
50     ThreadId* pThread = ConfigVariable::getThread(currentThreadKey);
51     if (pThread->getStatus() != ThreadId::Aborted)
52     {
53         pThread->setStatus(ThreadId::Done);
54         bdoUnlock = true;
55     }
56
57     //unregister thread
58     ConfigVariable::deleteThread(currentThreadKey);
59
60     delete me;
61
62     if (bdoUnlock)
63     {
64         UnlockPrompt();
65     }
66     return NULL;
67 }
68
69 void Runner::LockPrompt()
70 {
71     __LockSignal(&m_awakeScilabLock);
72     //free locker to release thread
73     __UnLock(&m_lock);
74     __Wait(&m_awakeScilab, &m_awakeScilabLock);
75     __UnLockSignal(&m_awakeScilabLock);
76 }
77
78 void Runner::UnlockPrompt()
79 {
80     __LockSignal(&m_awakeScilabLock);
81     __Signal(&m_awakeScilab);
82     __UnLockSignal(&m_awakeScilabLock);
83 }
84
85
86 void Runner::execAndWait(ast::Exp* _theProgram, ast::ExecVisitor *_visitor)
87 {
88     try
89     {
90         Runner *runMe = new Runner(_theProgram, _visitor);
91         __threadKey threadKey;
92         __threadId threadId;
93
94         //init locker
95         __InitLock(&m_lock);
96         //lock locker
97         __Lock(&m_lock);
98         //launch thread but is can't really start since locker is locked
99         __CreateThreadWithParams(&threadId, &threadKey, &Runner::launch, runMe);
100         runMe->setThreadId(threadId);
101         runMe->setThreadKey(threadKey);
102
103         //register thread
104         ConfigVariable::addThread(new ThreadId(threadId, threadKey));
105         //free locker to release thread && wait and of thread execution
106         LockPrompt();
107
108         types::ThreadId* pExecThread = ConfigVariable::getThread(threadKey);
109         if (pExecThread == NULL)
110         {
111             //call pthread_join to clean stack allocation
112             __WaitThreadDie(threadId);
113         }
114     }
115     catch (ScilabException se)
116     {
117         throw se;
118     }
119 }
120
121 void Runner::exec(ast::Exp* _theProgram, ast::ExecVisitor *_visitor)
122 {
123     m_theProgram = _theProgram;
124     m_visitor = _visitor;
125     __CreateThreadWithParams(&m_threadId, &m_threadKey, &Runner::launch, this);
126 }