EXPORTS
MyHeapFree
MyHeapAlloc
+StaticRunner_launch
+StaticRunner_isRunnerAvailable
+StaticRunner_isInterruptibleCommand
+StaticRunner_setInterruptibleCommand
#include "dynlib_ast.h"
}
+//#define DEBUG_THREAD
+
class EXTERN_AST ThreadManagement
{
private :
static __threadLock m_StartLock;
static __threadLock m_ParseLock;
static __threadLock m_StoreCommandLock;
- static __threadLock m_AstLock;
static __threadSignal m_ConsoleExecDone;
static __threadSignalLock m_ConsoleExecDoneLock;
static __threadSignal m_AwakeRunner;
static __threadSignalLock m_AwakeRunnerLock;
- static __threadSignal m_AstPending;
- static __threadSignalLock m_AstPendingLock;
+ static __threadSignal m_AvailableRunner;
+ static __threadSignalLock m_AvailableRunnerLock;
static __threadSignal m_StartPending;
static __threadSignalLock m_StartPendingLock;
static __threadSignal m_CommandStored;
static __threadSignalLock m_CommandStoredLock;
+ static __threadSignal m_RunMe;
+ static __threadSignalLock m_RunMeLock;
+
// used to avoid "Spurious Wakeups"
- static bool m_AstPendingWasSignalled;
+ static bool m_AvailableRunnerWasSignalled;
static bool m_ConsoleExecDoneWasSignalled;
static bool m_AwakeRunnerWasSignalled;
static bool m_StartPendingWasSignalled;
static bool m_CommandStoredWasSignalled;
+ static bool m_RunMeWasSignalled;
public :
static void initialize(void);
static void UnlockStoreCommand(void);
static void LockRunner(void);
static void UnlockRunner(void);
- static void LockAst(void);
- static void UnlockAst(void);
- static void SendAstPendingSignal(void);
- static void WaitForAstPendingSignal(void);
+ static void SendAvailableRunnerSignal(void);
+ static void WaitForAvailableRunnerSignal(void);
static void SendConsoleExecDoneSignal(void);
static void WaitForConsoleExecDoneSignal(void);
static void SendAwakeRunnerSignal(void);
static void WaitForStartPendingSignal(void);
static void SendCommandStoredSignal(void);
static void WaitForCommandStoredSignal(void);
+ static void SendRunMeSignal(void);
+ static void WaitForRunMeSignal(void);
};
if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
{
//return or resume
- ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
- if (pThreadId == NULL)
- {
- //no paused thread, so just go leave
- return;
- }
-
- //force exit without prompt of current thread ( via Aborted status )
- ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
- pMe->setStatus(ThreadId::Aborted);
-
- //resume previous execution thread
- pThreadId->resume();
-
+ ConfigVariable::DecreasePauseLevel();
return;
}
else
template <class T>
void RunVisitorT<T>::visitprivate(const SeqExp &e)
{
- types::ThreadId* pThreadMe = ConfigVariable::getThread(__GetCurrentThreadKey());
-
for (auto exp : e.getExps())
{
if (exp->isCommentExp())
continue;
}
- ThreadManagement::LockAst();
- if (pThreadMe && pThreadMe->getInterrupt())
+ // interrupt me to execute a prioritary command
+ while (StaticRunner_isInterruptibleCommand() == 1 && StaticRunner_isRunnerAvailable() == 1)
{
- ThreadManagement::SendAstPendingSignal();
- ThreadManagement::UnlockAst();
- pThreadMe->suspend();
+ StaticRunner_launch();
+ StaticRunner_setInterruptibleCommand(1);
}
- ThreadManagement::UnlockAst();
try
{
#include "threadmanagement.hxx"
-//#define DEBUG_THREAD
#ifdef DEBUG_THREAD
#include <iostream>
#endif // DEBUG_THREAD
__threadLock ThreadManagement::m_RunnerLock;
__threadLock ThreadManagement::m_ParseLock;
__threadLock ThreadManagement::m_StoreCommandLock;
-__threadLock ThreadManagement::m_AstLock;
__threadSignal ThreadManagement::m_ConsoleExecDone;
__threadSignalLock ThreadManagement::m_ConsoleExecDoneLock;
__threadSignal ThreadManagement::m_AwakeRunner;
__threadSignalLock ThreadManagement::m_AwakeRunnerLock;
-__threadSignal ThreadManagement::m_AstPending;
-__threadSignalLock ThreadManagement::m_AstPendingLock;
+__threadSignal ThreadManagement::m_AvailableRunner;
+__threadSignalLock ThreadManagement::m_AvailableRunnerLock;
__threadSignal ThreadManagement::m_StartPending;
__threadSignalLock ThreadManagement::m_StartPendingLock;
__threadSignal ThreadManagement::m_CommandStored;
__threadSignalLock ThreadManagement::m_CommandStoredLock;
-bool ThreadManagement::m_AstPendingWasSignalled = false;
+__threadSignal ThreadManagement::m_RunMe;
+__threadSignalLock ThreadManagement::m_RunMeLock;
+
+bool ThreadManagement::m_AvailableRunnerWasSignalled = false;
bool ThreadManagement::m_ConsoleExecDoneWasSignalled = false;
bool ThreadManagement::m_AwakeRunnerWasSignalled = false;
bool ThreadManagement::m_StartPendingWasSignalled = false;
bool ThreadManagement::m_CommandStoredWasSignalled = false;
+bool ThreadManagement::m_RunMeWasSignalled = false;
void ThreadManagement::initialize()
{
__InitLock(&m_StartLock);
__InitLock(&m_ParseLock);
__InitLock(&m_StoreCommandLock);
- __InitLock(&m_AstLock);
__InitSignal(&m_AwakeRunner);
__InitSignalLock(&m_AwakeRunnerLock);
__InitSignal(&m_ConsoleExecDone);
__InitSignalLock(&m_ConsoleExecDoneLock);
- __InitSignal(&m_AstPending);
- __InitSignalLock(&m_AstPendingLock);
+ __InitSignal(&m_AvailableRunner);
+ __InitSignalLock(&m_AvailableRunnerLock);
__InitSignal(&m_StartPending);
__InitSignalLock(&m_StartPendingLock);
__InitSignal(&m_CommandStored);
__InitSignalLock(&m_CommandStoredLock);
+
+ __InitSignal(&m_RunMe);
+ __InitSignalLock(&m_RunMeLock);
}
void ThreadManagement::LockStart(void)
__UnLock(&m_RunnerLock);
}
-void ThreadManagement::LockAst(void)
-{
-#ifdef DEBUG_THREAD
- std::cout << "[" << __GetCurrentThreadKey() << "] " << "LockAst" << std::endl;
-#endif // DEBUG_THREAD
- __Lock(&m_AstLock);
-}
-
-void ThreadManagement::UnlockAst(void)
-{
-#ifdef DEBUG_THREAD
- std::cout << "[" << __GetCurrentThreadKey() << "] " << "UnlockAst" << std::endl;
-#endif // DEBUG_THREAD
- __UnLock(&m_AstLock);
-}
-
-void ThreadManagement::SendAstPendingSignal(void)
+void ThreadManagement::SendAvailableRunnerSignal(void)
{
#ifdef DEBUG_THREAD
- std::cout << "[" << __GetCurrentThreadKey() << "] " << "SendAstPendingSignal" << std::endl;
+ std::cout << "[" << __GetCurrentThreadKey() << "] " << "SendAvailableRunnerSignal" << std::endl;
#endif // DEBUG_THREAD
- __LockSignal(&m_AstPendingLock);
- m_AstPendingWasSignalled = true;
- __Signal(&m_AstPending);
- __UnLockSignal(&m_AstPendingLock);
+ __LockSignal(&m_AvailableRunnerLock);
+ m_AvailableRunnerWasSignalled = true;
+ __Signal(&m_AvailableRunner);
+ __UnLockSignal(&m_AvailableRunnerLock);
}
-void ThreadManagement::WaitForAstPendingSignal(void)
+void ThreadManagement::WaitForAvailableRunnerSignal(void)
{
#ifdef DEBUG_THREAD
- std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForAstPendingSignal" << std::endl;
+ std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForAvailableRunnerSignal" << std::endl;
#endif // DEBUG_THREAD
- __LockSignal(&m_AstPendingLock);
- ThreadManagement::UnlockAst();
- m_AstPendingWasSignalled = false;
- while (m_AstPendingWasSignalled == false)
+ __LockSignal(&m_AvailableRunnerLock);
+ m_AvailableRunnerWasSignalled = false;
+ while (m_AvailableRunnerWasSignalled == false)
{
- __Wait(&m_AstPending, &m_AstPendingLock);
+ __Wait(&m_AvailableRunner, &m_AvailableRunnerLock);
}
- __UnLockSignal(&m_AstPendingLock);
+ __UnLockSignal(&m_AvailableRunnerLock);
}
}
__UnLockSignal(&m_CommandStoredLock);
}
+
+void ThreadManagement::SendRunMeSignal(void)
+{
+#ifdef DEBUG_THREAD
+ std::cout << "[" << __GetCurrentThreadKey() << "] " << "SendRunMeSignal" << std::endl;
+#endif // DEBUG_THREAD
+ __LockSignal(&m_RunMeLock);
+ m_RunMeWasSignalled = true;
+ __Signal(&m_RunMe);
+ __UnLockSignal(&m_RunMeLock);
+}
+
+void ThreadManagement::WaitForRunMeSignal(void)
+{
+#ifdef DEBUG_THREAD
+ std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForRunMeSignal" << std::endl;
+#endif // DEBUG_THREAD
+ __LockSignal(&m_RunMeLock);
+ m_RunMeWasSignalled = false;
+ while (m_RunMeWasSignalled == false)
+ {
+ __Wait(&m_RunMe, &m_RunMeLock);
+ }
+ __UnLockSignal(&m_RunMeLock);
+}
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
+ * Copyright (C) 2014-2015 - Scilab Enterprises - Cedric Delamarre
*
* This file must be used under the terms of the CeCILL.
* This source file is licensed as described in the file COPYING, which
#ifndef __RUNNER_HXX__
#define __RUNNER_HXX__
-#include <iostream>
#include "exp.hxx"
#include "execvisitor.hxx"
extern "C"
{
-#include "Thread_Wrapper.h"
#include "dynlib_core.h"
}
-#include "threadId.hxx"
-
-
class CORE_IMPEXP Runner
{
-private :
+public :
Runner(ast::Exp* _theProgram, ast::ExecVisitor *_visitor)
{
m_theProgram = _theProgram;
m_visitor = _visitor;
+ m_isConsoleCommand = false;
+ }
+
+ Runner(ast::Exp* _theProgram, ast::ExecVisitor *_visitor, bool _isConsoleCommand, bool _isInterruptible)
+ {
+ m_theProgram = _theProgram;
+ m_visitor = _visitor;
+ m_isConsoleCommand = _isConsoleCommand;
+ m_isInterruptible = _isInterruptible;
}
~Runner()
delete m_visitor;
}
-public :
-
- static void execAndWait(ast::Exp* _theProgram, ast::ExecVisitor *_visitor,
- bool _isInterruptible, bool _isPrioritary, bool _isConsoleCommand);
-
- void exec(ast::Exp* _theProgram, ast::ExecVisitor *_visitor);
-
ast::ExecVisitor *getVisitor()
{
return m_visitor;
return m_theProgram;
}
- __threadId getThreadId(void)
+ bool isConsoleCommand()
{
- return m_threadId;
+ return m_isConsoleCommand;
}
- void setThreadId(__threadId _threadId)
+ bool isInterruptible()
{
- m_threadId = _threadId;
+ return m_isInterruptible;
}
- __threadKey getThreadKey(void)
- {
- return m_threadKey;
- }
+private :
+ ast::Exp* m_theProgram;
+ ast::ExecVisitor* m_visitor;
+ bool m_isConsoleCommand;
+ bool m_isInterruptible;
- void setThreadKey(__threadKey _threadId)
- {
- m_threadKey = _threadId;
- }
+ // static members to manage execution
+};
-private :
- static void *launch(void *args);
+class StaticRunner
+{
+public:
+ static void launch(void);
+ static void setRunner(Runner* _RunMe);
+ static Runner* getRunner(void);
+ static bool isRunnerAvailable(void);
+ static bool isInterruptibleCommand(void);
+ static void setInterruptibleCommand(bool _isInterruptible);
+ static void execAndWait(ast::Exp* _theProgram, ast::ExecVisitor *_visitor,
+ bool _isInterruptible, bool _isPrioritary, bool _isConsoleCommand);
+ static void exec(ast::Exp* _theProgram, ast::ExecVisitor *_visitor);
-private :
- __threadKey m_threadKey;
- __threadId m_threadId;
- ast::Exp* m_theProgram;
- ast::ExecVisitor* m_visitor;
+private:
+ static Runner* m_RunMe;
+ static bool m_bInterruptibleCommand;
};
-#endif /* !__RUNNER_HXX__ */
+
+extern "C"
+{
+ void StaticRunner_launch(void);
+ int StaticRunner_isRunnerAvailable(void);
+ int StaticRunner_isInterruptibleCommand(void);
+ void StaticRunner_setInterruptibleCommand(int val);
+}
+
+#endif /* !__RUNNER_HXX__ */
\ No newline at end of file
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
+ * Copyright (C) 2015 - Scilab Enterprises - Cedric Delamarre
*
* This file must be used under the terms of the CeCILL.
* This source file is licensed as described in the file COPYING, which
#include "core_gw.hxx"
#include "function.hxx"
-#include "runner.hxx"
-#include "threadId.hxx"
-#include "double.hxx"
+#include "configvariable.hxx"
extern "C"
{
#include "charEncoding.h"
#include "localization.h"
#include "Scierror.h"
-
-#include "Thread_Wrapper.h"
}
types::Function::ReturnValue sci_abort(types::typed_list &in, int _iRetCount, types::typed_list &out)
return types::Function::Error;
}
- ThreadId* pThreadId = NULL;
- if (ConfigVariable::getLastPausedThread() == NULL)
- {
- throw ast::InternalAbort();
- }
- else
- {
- while ((pThreadId = ConfigVariable::getLastPausedThread()) != NULL)
- {
- __threadId id = pThreadId->getThreadId();
- pThreadId->abort();
- __WaitThreadDie(id);
- }
- }
-
+ throw ast::InternalAbort();
return types::Function::OK;
}
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
* Copyright (C) 2015 - Scilab Enterprises - Anais AUBERT
+ * Copyright (C) 2015 - Scilab Enterprises - Cedric Delamarre
*
* This file must be used under the terms of the CeCILL.
* This source file is licensed as described in the file COPYING, which
}
else
{
-
forceCloseMainScilabObject();
}
}
{
ConfigVariable::setExitStatus((int)dExit);
ConfigVariable::setForceQuit(true);
+ // go out without continue any execution
+ throw ast::InternalAbort();
}
return Function::OK;
}
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
+ * Copyright (C) 2015 - Scilab Enterprises - Cedric Delamarre
*
* This file must be used under the terms of the CeCILL.
* This source file is licensed as described in the file COPYING, which
#include "function.hxx"
#include "threadmanagement.hxx"
#include "configvariable.hxx"
-#include "threadId.hxx"
+#include "runner.hxx"
extern "C"
{
#include "charEncoding.h"
#include "localization.h"
#include "Scierror.h"
-
-#include "Thread_Wrapper.h"
}
types::Function::ReturnValue sci_pause(types::typed_list &in, int _iRetCount, types::typed_list &out)
ConfigVariable::IncreasePauseLevel();
- //unlock prompt thread.
- ThreadManagement::SendAwakeRunnerSignal();
+ // unlock console thread to display prompt again
ThreadManagement::SendConsoleExecDoneSignal();
- types::ThreadId* pThread = ConfigVariable::getLastRunningThread();
- if (pThread == NULL)
- {
- return types::Function::OK;
- }
-
//return to console so change mode to 2
int iOldMode = ConfigVariable::getPromptMode();
ConfigVariable::setPromptMode(2);
- //suspend current thread
- pThread->suspend();
-
- // Running from here means we have been awaken by some resume / abort
-
- //return from console so change mode to initial
- ConfigVariable::setPromptMode(iOldMode);
-
- ConfigVariable::DecreasePauseLevel();
- if (pThread->getStatus() == types::ThreadId::Aborted)
+ int iPauseLevel = ConfigVariable::getPauseLevel();
+ while (ConfigVariable::getPauseLevel() == iPauseLevel)
{
- throw ast::InternalAbort();
+ ThreadManagement::SendAwakeRunnerSignal();
+ ThreadManagement::WaitForRunMeSignal();
+ StaticRunner_launch();
}
+ //return from console so change mode to initial
+ ConfigVariable::setPromptMode(iOldMode);
return types::Function::OK;
}
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
+ * Copyright (C) 2015 - Scilab Enterprises - Cedric Delamarre
*
* This file must be used under the terms of the CeCILL.
* This source file is licensed as described in the file COPYING, which
types::Function::ReturnValue sci_quit(types::typed_list &in, int _iRetCount, types::typed_list &out)
{
//Terminates Scilab or decreases the pause level
-
- types::ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
- if (pThreadId)
+ if (ConfigVariable::getPauseLevel())
{
- __threadId id = pThreadId->getThreadId();
- pThreadId->abort();
- __WaitThreadDie(id);
-
+ ConfigVariable::DecreasePauseLevel();
}
else
{
ConfigVariable::setForceQuit(true);
+ throw ast::InternalAbort();
}
return types::Function::OK;
ConfigVariable::setPromptMode(0);
int iScript = 0;
- try
+ if (_pSEI->pstExec)
{
- if (_pSEI->pstExec)
- {
- //-e option
- Parser parser;
- parseCommandTask(&parser, _pSEI->iTimed != 0, _pSEI->pstExec);
-
- if (parser.getExitStatus() == Parser::Failed)
- {
- scilabWriteW(parser.getErrorMessage());
- }
- else if (parser.getControlStatus() != Parser::AllControlClosed)
- {
- _pSEI->iMultiLine = 1;
- }
- else
- {
- StoreConsoleCommand(_pSEI->pstExec);
- }
+ //-e option
+ Parser parser;
+ parseCommandTask(&parser, _pSEI->iTimed != 0, _pSEI->pstExec);
- if (parser.getTree())
- {
- delete parser.getTree();
- parser.setTree(NULL);
- }
- iMainRet = ConfigVariable::getExitStatus();
- iScript = 1;
+ if (parser.getExitStatus() == Parser::Failed)
+ {
+ scilabWriteW(parser.getErrorMessage());
+ }
+ else if (parser.getControlStatus() != Parser::AllControlClosed)
+ {
+ _pSEI->iMultiLine = 1;
}
- else if (_pSEI->pstFile)
+ else
+ {
+ StoreConsoleCommand(_pSEI->pstExec);
+ }
+
+ if (parser.getTree())
{
- //-f option execute exec('%s',-1)
- char *pstCommand = (char *)MALLOC(sizeof(char) * (strlen("exec(\"\",-1)") + strlen(_pSEI->pstFile) + 1));
- sprintf(pstCommand, "exec(\"%s\",-1)", _pSEI->pstFile);
-
- StoreConsoleCommand(pstCommand);
- FREE(pstCommand);
- iMainRet = ConfigVariable::getExitStatus();
- _pSEI->pstExec = NULL;
- _pSEI->pstFile = NULL;
- iScript = 1;
+ delete parser.getTree();
+ parser.setTree(NULL);
}
+ iMainRet = ConfigVariable::getExitStatus();
+ iScript = 1;
}
- catch (const ast::ScilabException& se)
+ else if (_pSEI->pstFile)
{
- scilabErrorW(se.GetErrorMessage().c_str());
+ //-f option execute exec('%s',-1)
+ char *pstCommand = (char *)MALLOC(sizeof(char) * (strlen("exec(\"\",-1)") + strlen(_pSEI->pstFile) + 1));
+ sprintf(pstCommand, "exec(\"%s\",-1)", _pSEI->pstFile);
+
+ StoreConsoleCommand(pstCommand);
+ FREE(pstCommand);
+ iMainRet = ConfigVariable::getExitStatus();
+ _pSEI->pstExec = NULL;
+ _pSEI->pstFile = NULL;
+ iScript = 1;
}
ConfigVariable::setPromptMode(2);
// thread to manage command stored
__CreateThreadWithParams(&threadIdCommand, &threadKeyCommand, &scilabReadAndExecCommand, _pSEI);
- __WaitThreadDie(threadIdCommand);
+#ifdef DEBUG_THREAD
+ std::cout << std::endl << "------------ threads summary ------------" << std::endl;
+ std::cout << "Main Thread : " << __GetCurrentThreadKey() << std::endl;
+ if (_pSEI->iStartConsoleThread)
+ {
+ std::cout << "scilabReadAndStore Thread : " << threadKeyConsole << std::endl;
+ }
+ std::cout << "scilabReadAndExecCommand Thread : " << threadKeyCommand << std::endl;
+ std::cout << "-----------------------------------------" << std::endl;
+#endif // DEBUG_THREAD
-#ifdef DEBUG
- std::cerr << "To end program press [ENTER]" << std::endl;
-#endif
+ do
+ {
+ ThreadManagement::WaitForRunMeSignal();
+ try
+ {
+ StaticRunner::launch();
+ }
+ catch (const ast::InternalAbort& /*ia*/)
+ {
+ // go out when exit/quit is called
+ }
+ ThreadManagement::SendAwakeRunnerSignal();
+ }
+ while (ConfigVariable::getForceQuit() == false);
return ConfigVariable::getExitStatus();
}
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
+ * Copyright (C) 2014-2015 - Scilab Enterprises - Cedric Delamarre
*
* This file must be used under the terms of the CeCILL.
* This source file is licensed as described in the file COPYING, which
using namespace ast;
-void *Runner::launch(void *args)
-{
- bool bdoUnlock = false;
- //try to lock locker ( waiting parent thread register me )
- ThreadManagement::LockRunner();
- //just release locker
- ThreadManagement::UnlockRunner();
+Runner* StaticRunner::m_RunMe = NULL;
+bool StaticRunner::m_bInterruptibleCommand = true;
- __threadKey currentThreadKey = __GetCurrentThreadKey();
- ThreadId* pThread = ConfigVariable::getThread(currentThreadKey);
-
- //exec !
- Runner *me = (Runner *)args;
+void StaticRunner::launch()
+{
+ // get the runner to execute
+ Runner* runMe = getRunner();
+ // set if the current comment is interruptible
+ setInterruptibleCommand(runMe->isInterruptible());
try
{
- me->getProgram()->accept(*(me->getVisitor()));
- //ConfigVariable::clearLastError();
+ runMe->getProgram()->accept(*(runMe->getVisitor()));
}
- catch (const ast::ScilabException& se)
+ catch (const ast::InternalError& se)
{
scilabErrorW(se.GetErrorMessage().c_str());
scilabErrorW(L"\n");
scilabErrorW(ostr.str().c_str());
ConfigVariable::resetWhereError();
}
+ catch (const ast::InternalAbort& ia)
+ {
+ // management of pause
+ if (ConfigVariable::getPauseLevel())
+ {
+ ConfigVariable::DecreasePauseLevel();
+ throw ia;
+ }
+
+ // close all scope before return to console scope
+ symbol::Context* pCtx = symbol::Context::getInstance();
+ while (pCtx->getScopeLevel() != SCOPE_CONSOLE)
+ {
+ pCtx->scope_end();
+ }
+
+ // management of exit/quit
+ if (ConfigVariable::getForceQuit())
+ {
+ throw ia;
+ }
+ }
if (getScilabMode() != SCILAB_NWNI && getScilabMode() != SCILAB_API)
{
// reset error state when new prompt occurs
ConfigVariable::resetError();
- //change thread status
- if (pThread->getStatus() != ThreadId::Aborted)
- {
- pThread->setStatus(ThreadId::Done);
- bdoUnlock = true;
- }
-
- ThreadManagement::LockAst();
- if (pThread->getInterrupt()) // non-prioritary
- {
- // Unlock prioritary thread waiting for
- // non-prioritary thread end this "SeqExp" execution.
- // This case appear when error is throw or when
- // non-prioritary execute this last SeqExp.
- pThread->setInterrupt(false);
- pThread->setInterruptible(false);
- ThreadManagement::SendAstPendingSignal();
- }
- ThreadManagement::UnlockAst();
-
- if (pThread->isConsoleCommand())
+ if (runMe->isConsoleCommand())
{
ThreadManagement::SendConsoleExecDoneSignal();
}
- //unregister thread
- ConfigVariable::deleteThread(currentThreadKey);
+ delete runMe;
+}
- delete me;
+void StaticRunner::setRunner(Runner* _RunMe)
+{
+ m_RunMe = _RunMe;
+}
- if (bdoUnlock)
- {
- ThreadManagement::SendAwakeRunnerSignal();
- }
+Runner* StaticRunner::getRunner(void)
+{
+ ThreadManagement::LockRunner();
+ Runner* tmp = m_RunMe;
+ m_RunMe = NULL;
+ ThreadManagement::UnlockRunner();
+ ThreadManagement::SendAvailableRunnerSignal();
+ return tmp;
+}
- return NULL;
+bool StaticRunner::isRunnerAvailable(void)
+{
+ ThreadManagement::LockRunner();
+ bool bOut = m_RunMe != NULL;
+ ThreadManagement::UnlockRunner();
+ return bOut;
}
-void Runner::execAndWait(ast::Exp* _theProgram, ast::ExecVisitor *_visitor,
- bool _isPrioritaryThread, bool _isInterruptibleThread, bool _isConsoleCommand)
+void StaticRunner::setInterruptibleCommand(bool _bInterruptibleCommand)
{
- try
- {
- Runner *runMe = new Runner(_theProgram, _visitor);
- __threadKey threadKey;
- __threadId threadId;
+ ThreadManagement::LockRunner();
+ m_bInterruptibleCommand = _bInterruptibleCommand;
+ ThreadManagement::UnlockRunner();
+}
- types::ThreadId* pInterruptibleThread = ConfigVariable::getLastRunningThread();
- if (_isPrioritaryThread)
- {
- if (pInterruptibleThread)
- {
- ThreadManagement::LockAst();
- if (pInterruptibleThread->isInterruptible())
- {
- pInterruptibleThread->setInterrupt(true);
- ThreadManagement::WaitForAstPendingSignal();
- }
- else
- {
- ThreadManagement::UnlockAst();
- __WaitThreadDie(pInterruptibleThread->getThreadId());
- pInterruptibleThread = NULL;
- }
- }
- }
- else if (pInterruptibleThread)
- {
- __WaitThreadDie(pInterruptibleThread->getThreadId());
- pInterruptibleThread = NULL;
- }
+bool StaticRunner::isInterruptibleCommand()
+{
+ ThreadManagement::LockRunner();
+ bool bIsInterruptibleCommand = m_bInterruptibleCommand;
+ ThreadManagement::UnlockRunner();
+ return bIsInterruptibleCommand;
+}
- // Lock the thread "Runner::launch" to be sure that all
- // stuff performed before the "WaitForAwakeRunnerSignal"
- // are done.
- ThreadManagement::LockRunner();
+void StaticRunner::execAndWait(ast::Exp* _theProgram, ast::ExecVisitor *_visitor,
+ bool _isPrioritaryThread, bool _isInterruptible, bool _isConsoleCommand)
+{
+ if (isRunnerAvailable())
+ {
+ // wait for managenement of last Runner
+ ThreadManagement::WaitForAvailableRunnerSignal();
+ }
- //launch thread but is can't really start since locker is locked
- __CreateThreadWithParams(&threadId, &threadKey, &Runner::launch, runMe);
- runMe->setThreadId(threadId);
- runMe->setThreadKey(threadKey);
+ // lock runner to be sure we are waiting for
+ // "AwakeRunner" signal before start execution
+ ThreadManagement::LockRunner();
+ Runner *runMe = new Runner(_theProgram, _visitor, _isConsoleCommand, _isInterruptible);
+ setRunner(runMe);
- //register thread
- types::ThreadId* pThread = new ThreadId(threadId, threadKey);
- ConfigVariable::addThread(pThread);
- pThread->setConsoleCommandFlag(_isConsoleCommand);
- pThread->setInterruptible(_isInterruptibleThread);
+ ThreadManagement::SendRunMeSignal();
+ ThreadManagement::WaitForAwakeRunnerSignal();
+}
- //free locker to release thread && wait and of thread execution
- ThreadManagement::WaitForAwakeRunnerSignal();
+void StaticRunner::exec(ast::Exp* _theProgram, ast::ExecVisitor *_visitor)
+{
+ ThreadManagement::LockRunner();
+ Runner *runMe = new Runner(_theProgram, _visitor);
+ setRunner(runMe);
+ ThreadManagement::UnlockRunner();
+ launch();
+}
- if (pInterruptibleThread && pInterruptibleThread->getInterrupt())
- {
- pInterruptibleThread->setInterrupt(false);
- pInterruptibleThread->resume();
- }
+void StaticRunner_launch(void)
+{
+ StaticRunner::launch();
+}
- types::ThreadId* pExecThread = ConfigVariable::getThread(threadKey);
- if (pExecThread == NULL)
- {
- //call pthread_join to clean stack allocation
- __WaitThreadDie(threadId);
- }
- }
- catch (const ast::ScilabException& se)
- {
- throw se;
- }
+int StaticRunner_isRunnerAvailable(void)
+{
+ return StaticRunner::isRunnerAvailable() ? 1 : 0;
}
-void Runner::exec(ast::Exp* _theProgram, ast::ExecVisitor *_visitor)
+int StaticRunner_isInterruptibleCommand(void)
{
- m_theProgram = _theProgram;
- m_visitor = _visitor;
- __CreateThreadWithParams(&m_threadId, &m_threadKey, &Runner::launch, this);
+ return StaticRunner::isInterruptibleCommand() ? 1 : 0;
}
+
+void StaticRunner_setInterruptibleCommand(int val)
+{
+ StaticRunner::setInterruptibleCommand(val == 1);
+}
\ No newline at end of file
exec = new ast::ExecVisitor();
}
- Runner::execAndWait(newTree, exec, isInterruptibleThread, isPrioritaryThread, isConsoleCommand);
+ StaticRunner::execAndWait(newTree, exec, isInterruptibleThread, isPrioritaryThread, isConsoleCommand);
//DO NOT DELETE tree or newTree, they was deleted by Runner or previously;
if (timed)
{
Parser parse;
wstring stSCI = ConfigVariable::getSCIPath();
-
stSCI += SCILAB_START;
+
ThreadManagement::LockParser();
parse.parseFile(stSCI, L"");
-
if (parse.getExitStatus() != Parser::Succeded)
{
scilabWriteW(parse.getErrorMessage());
ThreadManagement::UnlockParser();
return;
}
-
ThreadManagement::UnlockParser();
- execAstTask(parse.getTree(), _bSerialize, false, false, false, true, true, false);
+
+ ast::Exp* newTree = parse.getTree();
+ if (_bSerialize)
+ {
+ newTree = callTyper(parse.getTree());
+ }
+ StaticRunner::exec(newTree, new ast::ExecVisitor());
}
/*
{
Parser parse;
wstring stSCI = ConfigVariable::getSCIPath();
-
stSCI += SCILAB_QUIT;
+
ThreadManagement::LockParser();
parse.parseFile(stSCI, L"");
-
if (parse.getExitStatus() != Parser::Succeded)
{
scilabWriteW(parse.getErrorMessage());
ThreadManagement::UnlockParser();
return;
}
-
ThreadManagement::UnlockParser();
- execAstTask(parse.getTree(), _bSerialize, false, false, false, true, true, false);
+
+ ast::Exp* newTree = parse.getTree();
+ if (_bSerialize)
+ {
+ newTree = callTyper(parse.getTree());
+ }
+ StaticRunner::exec(newTree, new ast::ExecVisitor());
}