Merge branch 'master' into polymorphic_extern_classes
[nit.git] / lib / pnacl.nit
index a63e7ca..bc876c0 100644 (file)
 #
 # 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"
@@ -39,6 +37,15 @@ module pnacl is platform
        #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>
 
        #define MAX_DICTIONARY_QUEUE_SIZE 200
        #define MAX_MESSAGE_QUEUE_SIZE 10
@@ -307,17 +314,14 @@ module pnacl is platform
        /* 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 */
@@ -637,11 +641,8 @@ class PnaclStream
 
        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
 
@@ -718,9 +719,44 @@ class PnaclApp
 
        # 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