123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153(*********************************************************************************)(* Ojs-base *)(* *)(* Copyright (C) 2014-2021 INRIA. All rights reserved. *)(* *)(* This program is free software; you can redistribute it and/or modify *)(* it under the terms of the GNU General Public License as *)(* published by the Free Software Foundation, version 3 of the License. *)(* *)(* This program is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Library General Public License for more details. *)(* *)(* You should have received a copy of the GNU General Public *)(* License along with this program; if not, write to the Free Software *)(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)(* 02111-1307 USA *)(* *)(* As a special exception, you have permission to link this program *)(* with the OCaml compiler and distribute executables, as long as you *)(* follow the requirements of the GNU GPL in regard to all of the *)(* software in the executable aside from the OCaml compiler. *)(* *)(* Contact: Maxence.Guesdon@inria.fr *)(* *)(*********************************************************************************)(** *)let(>>=)=Lwt.(>>=)typecall_id=int[@@derivingyojson]moduleIdmap=Map.Make(structtypet=call_idletcompare=Stdlib.compareend)moduleJ=Yojson.Safetypejson=J.tletgensym=letcpt=ref0infun()->incrcpt;!cptmoduletypeB=sigincludeTypes.App_msgtypeapp_server_msg+=|SCallofcall_id*app_server_msg|SReturnofcall_id*app_server_msgtypeapp_client_msg+=|Callofcall_id*app_client_msg|Returnofcall_id*app_client_msgvalpack_server_call:call_id->app_server_msg->app_server_msgvalpack_server_return:call_id->app_server_msg->app_server_msgvalpack_client_call:call_id->app_client_msg->app_client_msgvalpack_client_return:call_id->app_client_msg->app_client_msgendmoduleBase(P:Types.App_msg)=structtypeapp_server_msg=P.app_server_msg=..[@@derivingyojson]typeapp_server_msg+=|SCallofcall_id*app_server_msg|SReturnofcall_id*app_server_msg[@@derivingyojson]typeapp_client_msg=P.app_client_msg=..[@@derivingyojson]typeapp_client_msg+=|Callofcall_id*app_client_msg|Returnofcall_id*app_client_msg[@@derivingyojson]letpack_server_callcall_idmsg=SCall(call_id,msg)letpack_server_returncall_idmsg=SReturn(call_id,msg)letpack_client_callcall_idmsg=Call(call_id,msg)letpack_client_returncall_idmsg=Return(call_id,msg)endmoduletypePspec=sigtypeapp_server_msg=..typeapp_client_msg=..valpack_call_msg:call_id->app_server_msg->app_server_msgvalpack_return_msg:call_id->app_server_msg->app_server_msgendmoduleMake(P:Pspec)=structtypeapp_server_msg=P.app_server_msg=..typeapp_client_msg=P.app_client_msg=..typet={mutablepending:app_client_msgLwt_condition.tIdmap.t;send:app_server_msg->unitLwt.t;}letrpc_handlersend={pending=Idmap.empty;send}letcalltmsgcallback=letid=gensym()inletcond=Lwt_condition.create()int.pending<-Idmap.addidcondt.pending;letmsg=P.pack_call_msgidmsgint.sendmsg>>=fun()->Lwt_condition.waitcond>>=callbackletreturntcall_idmsg=letmsg=P.pack_return_msgcall_idmsgint.sendmsgleton_returntcall_idmsg=matchIdmap.findcall_idt.pendingwith|exceptionNot_found->()|cond->begint.pending<-Idmap.removecall_idt.pending;Lwt_condition.signalcondmsgendendmoduletypeS=sigtypeapp_server_msgtypeapp_client_msgtypetvalrpc_handler:(app_server_msg->unitLwt.t)->tvalcall:t->app_server_msg->(app_client_msg->'aLwt.t)->'aLwt.tvalreturn:t->call_id->app_server_msg->unitLwt.tvalon_return:t->call_id->app_client_msg->unitendmoduleMake_server(P:B)=structmodulePspec=structtypeapp_server_msg=P.app_server_msg=..typeapp_client_msg=P.app_client_msg=..letpack_call_msg=P.pack_server_callletpack_return_msg=P.pack_server_returnendincludeMake(Pspec)endmoduleMake_client(P:B)=structmodulePspec=structtypeapp_server_msg=P.app_client_msg=..typeapp_client_msg=P.app_server_msg=..letpack_call_msg=P.pack_client_callletpack_return_msg=P.pack_client_returnendincludeMake(Pspec)end