Threads execution managemement.
[scilab.git] / scilab / modules / core / src / cpp / storeCommand.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - 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 extern "C"
14 {
15 #define NOMINMAX
16 #include "storeCommand.h"
17 #include "Thread_Wrapper.h"
18
19     // mmap
20 #ifdef _MSC_VER
21 #include "mmapWindows.h"
22 #else
23 #include <sys/mman.h>
24 #ifndef MAP_ANONYMOUS
25 # define MAP_ANONYMOUS MAP_ANON
26 #endif
27 #endif
28
29 }
30
31 #include "parser.hxx"
32 #include "execvisitor.hxx"
33 #include "tasks.hxx"
34 #include "scilabWrite.hxx"
35 #include "scilabexception.hxx"
36 #include "localization.hxx"
37 #include "runner.hxx"
38
39 using namespace ast;
40 /*--------------------------------------------------------------------------*/
41 /*
42  *  Command queue functions
43  *  This function is used to store Scilab command in a queue
44  *
45  *  PUBLIC : int StoreCommand( char *command)
46  *           int C2F(ismenu)()
47  *           int C2F(getmen)(char * btn_cmd,int * lb, int * entry)
48  */
49 /*--------------------------------------------------------------------------*/
50 struct CommandRec
51 {
52     char*   m_command;              /* command info one string two integers */
53     int     m_isInterruptible;      /* 1 if the command execution can be interrupted */
54     int     m_consoleCmd;           /* 1 if the command come from console */
55     CommandRec(char* command, int isInterruptible, int consoleCmd) : m_command(command), m_isInterruptible(isInterruptible), m_consoleCmd(consoleCmd) {}
56 };
57 /*--------------------------------------------------------------------------*/
58 /* Extern Signal to say we git a StoreCommand. */
59 extern "C"
60 {
61     extern __threadSignal LaunchScilab;
62 }
63 /*--------------------------------------------------------------------------*/
64 static std::list<CommandRec> commandQueue;
65 static std::list<CommandRec> commandQueuePrioritary;
66 //static __threadLock commandQueueSingleAccess = __StaticInitLock;
67 static void release(void);
68 static __threadLock* getCommandQueueSingleAccess()
69 {
70     static __threadLock* ptr = NULL;
71     if (!ptr)
72     {
73         ptr = (__threadLock*)mmap(0, sizeof(__threadLock), PROT_READ | PROT_WRITE, MAP_SHARED |  MAP_ANONYMOUS, -1, 0);
74 #ifdef _MSC_VER
75         *ptr =  __StaticInitLock;
76 #else
77         __InitSignalLock(ptr);
78 #endif
79         atexit(release);
80     }
81     return ptr;
82 }
83
84 static void release(void)
85 {
86     if (getCommandQueueSingleAccess())
87     {
88         __UnLock(getCommandQueueSingleAccess());
89     }
90 }
91 /*--------------------------------------------------------------------------*/
92 int StoreCommand (char *command)
93 {
94     return StoreCommandWithFlag (command, 1);
95 }
96
97 /*--------------------------------------------------------------------------*/
98 /*
99  * try to execute a command or add it to the end of command queue
100  */
101 int StoreCommandWithFlag (char *command, int isInterruptible)
102 {
103     __Lock(getCommandQueueSingleAccess());
104     commandQueue.emplace_back(os_strdup(command), isInterruptible, 0);
105     __UnLock(getCommandQueueSingleAccess());
106     __Signal(&LaunchScilab);
107
108     return 0;
109 }
110 /*--------------------------------------------------------------------------*/
111 /*
112  * try to execute a command or add it to the _BEGINNING_ of command queue
113  */
114 int StoreConsoleCommandWithFlag (char *command, int isInterruptible)
115 {
116     __Lock(getCommandQueueSingleAccess());
117     commandQueuePrioritary.emplace_back(os_strdup(command), isInterruptible, 1);
118     __UnLock(getCommandQueueSingleAccess());
119     __Signal(&LaunchScilab);
120     Runner::UnlockPrompt();
121     return 0;
122 }
123
124 int StorePrioritaryCommandWithFlag (char *command, int isInterruptible)
125 {
126     __Lock(getCommandQueueSingleAccess());
127     commandQueuePrioritary.emplace_back(os_strdup(command), isInterruptible, 0);
128     __UnLock(getCommandQueueSingleAccess());
129     __Signal(&LaunchScilab);
130     Runner::UnlockPrompt();
131     return 0;
132 }
133 /*--------------------------------------------------------------------------*/
134 int isEmptyCommandQueue(void)
135 {
136     return (commandQueuePrioritary.empty() && commandQueue.empty());
137 }
138 /*--------------------------------------------------------------------------*/
139 /*
140  * Gets info on the first queue element
141  * and remove it from the queue
142  */
143 int GetCommand (char** cmd, int* piConsoleCmd)
144 {
145     int isInterruptible = 0;
146     __Lock(getCommandQueueSingleAccess());
147
148     if (commandQueuePrioritary.empty() == false)
149     {
150         *cmd = os_strdup(commandQueuePrioritary.front().m_command);
151         isInterruptible = commandQueuePrioritary.front().m_isInterruptible;
152         *piConsoleCmd = commandQueuePrioritary.front().m_consoleCmd;
153
154         FREE (commandQueuePrioritary.front().m_command);
155         commandQueuePrioritary.pop_front();
156     }
157     else if (commandQueue.empty() == false)
158     {
159         *cmd = os_strdup(commandQueue.front().m_command);
160         isInterruptible = commandQueue.front().m_isInterruptible;
161         *piConsoleCmd = commandQueue.front().m_consoleCmd;
162
163         FREE (commandQueue.front().m_command);
164         commandQueue.pop_front();
165     }
166     __UnLock(getCommandQueueSingleAccess());
167
168     return isInterruptible;
169 }
170 /*--------------------------------------------------------------------------*/
171 int ismenu(void)
172 {
173     //#pragma message("WARNING : ismenu is deprecated. It will be removed _BEFORE_ Scilab 6.0.")
174     // FIXME : Do not forget to remove me.
175     return 0;
176 }
177 /*--------------------------------------------------------------------------*/
178 /* menu/button info for Scilab */
179 int C2F(getmen)(char * btn_cmd, int * lb, int * entry)
180 {
181     //#pragma message("WARNING : C2F(getmen) is deprecated. It will be removed _BEFORE_ Scilab 6.0.")
182     // FIXME : Do not forget to remove me.
183     return 0;
184 }
185 /*--------------------------------------------------------------------------*/