thread management fixed.
[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 StoreConsoleCommand(char *command)
47  *           int StorePrioritaryCommand(char *command)
48  *           int C2F(ismenu)()
49  *           int C2F(getmen)(char * btn_cmd,int * lb, int * entry)
50  */
51 /*--------------------------------------------------------------------------*/
52 struct CommandRec
53 {
54     char*   m_command;              /* command info one string two integers */
55     int     m_isInterruptible;      /* 1 if the command execution can be interrupted */
56     int     m_isPrioritary;         /* 1 if the command is prioritary */
57     int     m_isConsole;            /* 1 if the command come from console */
58     CommandRec(char* command, int isInterruptible, int isPrioritary, int isConsole) : m_command(command), m_isInterruptible(isInterruptible), m_isPrioritary(isPrioritary), m_isConsole(isConsole) {}
59 };
60 /*--------------------------------------------------------------------------*/
61 /* Extern Signal to say we git a StoreCommand. */
62 extern "C"
63 {
64     extern __threadSignal LaunchScilab;
65 }
66 /*--------------------------------------------------------------------------*/
67 static std::list<CommandRec> commandQueue;
68 static std::list<CommandRec> commandQueuePrioritary;
69 //static __threadLock commandQueueSingleAccess = __StaticInitLock;
70 static void release(void);
71 static __threadLock* getCommandQueueSingleAccess()
72 {
73     static __threadLock* ptr = NULL;
74     if (!ptr)
75     {
76         ptr = (__threadLock*)mmap(0, sizeof(__threadLock), PROT_READ | PROT_WRITE, MAP_SHARED |  MAP_ANONYMOUS, -1, 0);
77 #ifdef _MSC_VER
78         *ptr =  __StaticInitLock;
79 #else
80         __InitSignalLock(ptr);
81 #endif
82         atexit(release);
83     }
84     return ptr;
85 }
86
87 static void release(void)
88 {
89     if (getCommandQueueSingleAccess())
90     {
91         __UnLock(getCommandQueueSingleAccess());
92     }
93 }
94 /*--------------------------------------------------------------------------*/
95 int StoreCommand(char *command)
96 {
97     __Lock(getCommandQueueSingleAccess());
98     commandQueue.emplace_back(os_strdup(command),
99                               /*is prioritary*/ 0,
100                               /* is interruptible*/ 1,
101                               /* from console */ 0);
102     __UnLock(getCommandQueueSingleAccess());
103     __Signal(&LaunchScilab);
104
105     return 0;
106 }
107
108 int StoreConsoleCommand(char *command)
109 {
110     __Lock(getCommandQueueSingleAccess());
111     commandQueuePrioritary.emplace_back(os_strdup(command),
112                                         /*is prioritary*/ 1,
113                                         /* is interruptible*/ 1,
114                                         /* from console */ 1);
115     __UnLock(getCommandQueueSingleAccess());
116     __Signal(&LaunchScilab);
117     Runner::UnlockPrompt();
118     return 0;
119 }
120
121 int StorePrioritaryCommand(char *command)
122 {
123     __Lock(getCommandQueueSingleAccess());
124     commandQueuePrioritary.emplace_back(os_strdup(command),
125                                         /*is prioritary*/ 1,
126                                         /* is interruptible*/ 0,
127                                         /* from console */ 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 the next command to execute
141  * and remove it from the queue
142  */
143 int GetCommand (char** cmd, int* piInterruptible, int* piPrioritary, int* piConsole)
144 {
145     int iCommandReturned = 0;
146
147     __Lock(getCommandQueueSingleAccess());
148     if (commandQueuePrioritary.empty() == false)
149     {
150         *cmd = os_strdup(commandQueuePrioritary.front().m_command);
151         *piInterruptible = commandQueuePrioritary.front().m_isInterruptible;
152         *piPrioritary = commandQueuePrioritary.front().m_isPrioritary;
153         *piConsole = commandQueuePrioritary.front().m_isConsole;
154
155         FREE (commandQueuePrioritary.front().m_command);
156         commandQueuePrioritary.pop_front();
157
158         iCommandReturned = 1;
159     }
160     else if (commandQueue.empty() == false)
161     {
162         *cmd = os_strdup(commandQueue.front().m_command);
163         *piInterruptible = commandQueue.front().m_isInterruptible;
164         *piPrioritary = commandQueue.front().m_isPrioritary;
165         *piConsole = commandQueue.front().m_isConsole;
166
167         FREE (commandQueue.front().m_command);
168         commandQueue.pop_front();
169
170         iCommandReturned = 1;
171     }
172     __UnLock(getCommandQueueSingleAccess());
173
174     return iCommandReturned;
175 }
176 /*--------------------------------------------------------------------------*/
177 int ismenu(void)
178 {
179     //#pragma message("WARNING : ismenu is deprecated. It will be removed _BEFORE_ Scilab 6.0.")
180     // FIXME : Do not forget to remove me.
181     return 0;
182 }
183 /*--------------------------------------------------------------------------*/
184 /* menu/button info for Scilab */
185 int C2F(getmen)(char * btn_cmd, int * lb, int * entry)
186 {
187     //#pragma message("WARNING : C2F(getmen) is deprecated. It will be removed _BEFORE_ Scilab 6.0.")
188     // FIXME : Do not forget to remove me.
189     return 0;
190 }
191 /*--------------------------------------------------------------------------*/