# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-#
-# Targets the PNaCl platform
+
+# Provides PNaCl support for Nit.
#
# To use this module and compile for PNaCl, you must install the
# NaCl SDK (This file is based on Pepper 33).
# If NACL_SDK_ROOT is not set in your PATH, you have to work in
# 'nacl_sdk/pepper_your_pepper_version/getting_started/your_project_folder'.
-#
-# Provides PNaCl support for Nit.
module pnacl is platform
-`{
- #include <unistd.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <pthread.h>
+
+import standard
+intrude import standard::stream
+
+in "C Header" `{
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppp.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/c/ppp_messaging.h"
#include "ppapi/c/ppb_var_dictionary.h"
#include "ppapi/c/ppb_var_array.h"
+`}
+
+`{
+ #include <unistd.h>
+ #include <stddef.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <pthread.h>
+ #include <poll.h>
#define MAX_DICTIONARY_QUEUE_SIZE 200
#define MAX_MESSAGE_QUEUE_SIZE 10
/* This function is called by Nit when using check_dictionary,
returns the dictionary at the head of the queue. */
void* NitHandleDictionary() {
- while(1) {
- struct PP_Var dictionary = DequeueDictionary();
- PnaclApp_handle_dictionary(app, &dictionary);
- }
+ struct PP_Var dictionary = DequeueDictionary();
+ PnaclApp_handle_dictionary(app, &dictionary);
+ return 0;
}
/* This function is called By Nit when waiting for a user input. */
char* NitHandleMessage() {
- while(1) {
- return DequeueMessage();
- }
+ return DequeueMessage();
}
/* Entry point */
}
/* Hack in order to avoid the problem with file. */
- int poll(void *fds, int nfds, int timeout) { return 0; }
+ int poll(struct pollfd* fds, nfds_t nfds, int timeout) { return 0; }
`}
# Nit class representing a Pepper C API PP_Var typed as a Dictionary.
# A stream for PNaCl, redefines basic input and output methods.
class PnaclStream
- super PollableIStream
- super OStream
- super BufferedIStream
+ super PollableReader
+ super Writer
+ super BufferedReader
init do prepare_buffer(10)
redef fun eof do return end_reached
- # write method sends now a message to JS.
- redef fun write(s: Text)
- do
- app.post_message s.to_s
- end
+ # Redefintion of 'write' to send messages to the browser.
+ redef fun write(s: Text) do app.post_message s.to_s
redef fun is_writable: Bool do return true
# fill_buffer now checks for a message in the message queue which is filled by user inputs.
redef fun fill_buffer
do
- _buffer.clear
_buffer_pos = 0
- _buffer.append check_message.to_s
+ var nns = check_message
+ var nslen = nns.cstring_length
+ _buffer_length = nslen
+ nns.copy_to(buffer, nslen, 0, 0)
end
end
# Checks if there is a dictionary in the queue, and if so the dictionary is handled automatically.
fun check_dictionary `{
- while(1) {
- NitHandleDictionary();
- }
+ NitHandleDictionary();
`}
+
+ # Infinite loop on check_dictionary
+ fun run
+ do
+ loop
+ check_dictionary
+ end
+ end
end
+
+# Creates a new thread for Nit.
+#
+# This function launches the Nit main on a new thread.
+# Its purpose is to allow Nit to be still operational after an exit when needed,
+# because reloading the page may not be an option.
+#
+# Should only be used within the 'exit' before stopping the current thread
+# when the Nit execution causes a crash.
+#
+# REQUIRE: g_nit_thread and WrapperNitMain are set.
+fun create_thread `{
+ pthread_create(&g_nit_thread, NULL, &WrapperNitMain, NULL);
+`}
+
+# Calls 'pthread_exit on current thread.
+fun exit_thread(exit_value: Int) `{
+ pthread_exit((void*) exit_value);
+`}
+
+# Redef of exit in order to avoid the module to crash by terminating only the Nit thread.
+redef fun exit(exit_value: Int)
+do
+ var dictionary = new PepperDictionary
+ dictionary["exit"] = exit_value
+ app.post_dictionary dictionary
+ exit_thread exit_value
+end
+
fun app: PnaclApp do return once new PnaclApp