Commits

Anonymous committed 2b2bf2f

Fixed another set of selective receive bugs in erlang_js

Comments (0)

Files changed (5)

apps/erlang_js/c_src/spidermonkey_drv.c

   driver_output_term(port, terms, term_count);
 }
 
-static void send_ok_response(spidermonkey_drv_t *dd) {
-  ErlDrvTermData terms[] = {ERL_DRV_ATOM, dd->atom_ok};
-  send_output(dd->port, terms, sizeof(terms) / sizeof(terms[0]));
-}
-
-static void send_error_string_response(spidermonkey_drv_t *dd, const char *msg) {
-  ErlDrvTermData terms[] = {ERL_DRV_ATOM, dd->atom_error,
-			    ERL_DRV_BUF2BINARY, (ErlDrvTermData) msg, strlen(msg),
+static void send_ok_response(spidermonkey_drv_t *dd, const char *call_id) {
+  ErlDrvTermData terms[] = {ERL_DRV_BUF2BINARY, (ErlDrvTermData) call_id, strlen(call_id),
+			    ERL_DRV_ATOM, dd->atom_ok,
 			    ERL_DRV_TUPLE, 2};
   send_output(dd->port, terms, sizeof(terms) / sizeof(terms[0]));
 }
 
-static void send_string_response(spidermonkey_drv_t *dd, const char *result) {
-  ErlDrvTermData terms[] = {ERL_DRV_ATOM, dd->atom_ok,
-			    ERL_DRV_BUF2BINARY, (ErlDrvTermData) result, strlen(result),
-			    ERL_DRV_TUPLE, 2};
+static void send_error_string_response(spidermonkey_drv_t *dd, const char *call_id, const char *msg) {
+  ErlDrvTermData terms[] = {ERL_DRV_BUF2BINARY, (ErlDrvTermData) call_id, strlen(call_id),
+                            ERL_DRV_ATOM, dd->atom_error,
+			    ERL_DRV_BUF2BINARY, (ErlDrvTermData) msg, strlen(msg),
+			    ERL_DRV_TUPLE, 3};
   send_output(dd->port, terms, sizeof(terms) / sizeof(terms[0]));
 }
 
-static void unknown_command(spidermonkey_drv_t *dd) {
-  ErlDrvTermData terms[] = {ERL_DRV_ATOM, dd->atom_error,
+static void send_string_response(spidermonkey_drv_t *dd, const char *call_id, const char *result) {
+  ErlDrvTermData terms[] = {ERL_DRV_BUF2BINARY, (ErlDrvTermData) call_id, strlen(call_id),
+                            ERL_DRV_ATOM, dd->atom_ok,
+			    ERL_DRV_BUF2BINARY, (ErlDrvTermData) result, strlen(result),
+			    ERL_DRV_TUPLE, 3};
+  send_output(dd->port, terms, sizeof(terms) / sizeof(terms[0]));
+}
+
+static void unknown_command(spidermonkey_drv_t *dd, const char *call_id) {
+  ErlDrvTermData terms[] = {ERL_DRV_BUF2BINARY, (ErlDrvTermData) call_id, strlen(call_id),
+                            ERL_DRV_ATOM, dd->atom_error,
 			    ERL_DRV_ATOM, dd->atom_unknown_cmd,
-			    ERL_DRV_TUPLE, 2};
+			    ERL_DRV_TUPLE, 3};
   send_output(dd->port, terms, sizeof(terms) / sizeof(terms[0]));
 }
 
   ErlDrvBinary *args = ev->binv[1];
   char *data = args->orig_bytes;
   char *command = read_command(&data);
+  char *call_id = read_string(&data);
   char *result = NULL;
   if (strncmp(command, "ej", 2) == 0) {
     char *filename = read_string(&data);
     char *code = read_string(&data);
     result = sm_eval(dd->vm, filename, code, 1);
     if (strstr(result, "{\"error\"") != NULL) {
-      send_error_string_response(dd, result);
+      send_error_string_response(dd, call_id, result);
     }
     else {
-      send_string_response(dd, result);
+      send_string_response(dd, call_id, result);
     }
     driver_free(filename);
     driver_free(code);
     char *code = read_string(&data);
     result = sm_eval(dd->vm, filename, code, 0);
     if (result == NULL) {
-      send_ok_response(dd);
+      send_ok_response(dd, call_id);
     }
     else {
-      send_error_string_response(dd, result);
+      send_error_string_response(dd, call_id, result);
       driver_free(result);
     }
     driver_free(filename);
   }
   else if (strncmp(command, "sd", 2) == 0) {
     dd->shutdown = 1;
-    send_ok_response(dd);
+    send_ok_response(dd, call_id);
   }
   else {
-    unknown_command(dd);
+    unknown_command(dd, call_id);
   }
   driver_free(command);
+  driver_free(call_id);
 }

apps/erlang_js/src/js_cache.erl

 -behaviour(gen_server).
 
 %% API
--export([start_link/0, store/2, delete/1, fetch/1]).
+-export([start_link/0, store/2, delete/1, fetch/1, call_id/0]).
 
 %% gen_server callbacks
 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
 
 -define(SERVER, ?MODULE).
 
--record(state, {cache=gb_trees:empty()}).
+-record(state, {cache=gb_trees:empty(), call_id=0}).
 
 start_link() ->
     gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
 fetch(Key) ->
     gen_server:call(?SERVER, {fetch, Key}).
 
+call_id() ->
+    gen_server:call(?SERVER, call_id).
+
 init([]) ->
     {ok, #state{}}.
 
+handle_call(call_id, _From, #state{call_id=CurrVal}=State) ->
+    Id = list_to_binary(["$js", integer_to_list(CurrVal)]),
+    NewVal = if
+                 CurrVal == 1000000 ->
+                     0;
+                 true ->
+                     CurrVal + 1
+             end,
+    {reply, Id, State#state{call_id=NewVal}};
+
 handle_call({fetch, Key}, _From, #state{cache=Cache}=State) ->
     Result = case gb_trees:lookup(Key, Cache) of
                  {value, Value} ->

apps/erlang_js/src/js_driver.erl

     case Initializer(Port) of
         ok ->
             {ok, Port};
-        Error ->
+        {error, Error} ->
             error_logger:error_report(Error),
             throw({error, init_failed})
     end;
     case InitMod:InitFun(Port) of
         ok ->
             {ok, Port};
-        Error ->
+        {error, Error} ->
             error_logger:error_report(Error),
             throw({error, init_failed})
     end.
         {error, ErrorJson} when is_binary(ErrorJson) ->
             {struct, [{<<"error">>, {struct, Error}}]} = mochijson2:decode(ErrorJson),
             {error, Error};
-        Result ->
-            Result
+        ok ->
+            ok
     end.
 
 eval_js(Ctx, Js) ->
                 {struct, [{<<"error">>, Error}]} ->
                     {error, Error}
             end;
-        Error ->
-            Error
+        {error, Error} ->
+            {error, Error}
     end.
 
 %% Internal functions
     end.
 
 call_driver(Ctx, Command, Args, Timeout) ->
-    Marshalled = js_drv_comm:pack(Command, Args),
+    CallId = js_cache:call_id(),
+    Marshalled = js_drv_comm:pack(Command, [CallId] ++ Args),
     port_command(Ctx, Marshalled),
     Result = receive
-                 Response ->
-                     Response
+                 {CallId, ok} ->
+                     ok;
+                 {CallId, ok, R} ->
+                     {ok, R};
+                 {CallId, error, Error} ->
+                     {error, Error}
              after Timeout ->
                      {error, timeout}
              end,

apps/riak/src/riak_client.erl

     receive
         {ReqId, done} -> {ok, Acc};
         {ReqId,{mr_results,Res}} ->
-            io:format("Got mr_results: ~p~n", [Res]),
             collect_mr_results(ReqId,Timeout,Acc++Res)
     after Timeout ->
             {error, timeout}

apps/riak/src/riak_js.erl

             {error, Error}
     end.
 
-
-invoke_map(JsCtx, CSums, Args, Class, FunName, undefined) when Class =:= <<"Riak">> ->
-    RealFunName = list_to_binary([Class, <<".">>, FunName]),
-    case js:call(JsCtx, RealFunName, Args) of
-        {ok, Results} ->
-            {Results, CSums};
-        {error, Error} ->
-            {{error, Error}, CSums}
-    end;
-
 invoke_map(JsCtx, CSums, Args, undefined, FunName, F) ->
     MD5 = erlang:md5(F),
     {Continue, NewCSums} = case needs_defining(CSums, FunName, MD5) of
             end;
         Err ->
             {Err, CSums}
+    end;
+
+invoke_map(JsCtx, CSums, Args, Class, FunName, undefined) ->
+    RealFunName = list_to_binary([Class, <<".">>, FunName]),
+    case js:call(JsCtx, RealFunName, Args) of
+        {ok, Results} ->
+            {Results, CSums};
+        {error, Error} ->
+            {{error, Error}, CSums}
     end.
 
 invoke_reduce(JsCtx, CSums, Args, Class, FunName, undefined) when Class =:= <<"Riak">> ->
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.