Load 57 into trunk.
[nativeclient.git] / tools / libsrpc / nacl_srpc.h
blob5d80d21274f92fe7a30af6a349b85bf3c2feec42
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #ifndef NATIVE_CLIENT_TOOLS_LIBSRPC_NACL_SRPC_H_
34 #define NATIVE_CLIENT_TOOLS_LIBSRPC_NACL_SRPC_H_
36 /**
37 * @file
38 * Defines the Simple RPC (SRPC) API for Native Client applications and for
39 * trusted clients communicating using SRPC.
41 * @addtogroup SRPC
42 * @{
45 #include <stdarg.h>
48 * TODO break this file into separate files for sdk and service_runtime
49 * inclusion.
51 #ifdef __native_client__
52 # include <stdint.h>
53 # include <sys/types.h>
54 # include <sys/nacl_imc_api.h>
55 # include <pthread.h>
57 * Avoid emacs' penchant for auto-indenting extern "C" blocks.
59 # ifdef __cplusplus
60 # define EXTERN_C_BEGIN extern "C" {
61 # define EXTERN_C_END }
62 # else
63 # define EXTERN_C_BEGIN
64 # define EXTERN_C_END
65 # endif /* __cplusplus */
66 /**
67 * Contains a file descriptor for use as an IMC channel.
69 typedef int NaClSrpcImcDescType;
70 #else
71 # include "native_client/include/portability.h"
72 # include "native_client/include/nacl_base.h"
73 # include "native_client/service_runtime/nacl_log.h"
74 # include "native_client/service_runtime/nrd_xfer_lib/nrd_all_modules.h"
75 # include "native_client/service_runtime/nrd_xfer_lib/nrd_xfer.h"
76 # include "native_client/service_runtime/nrd_xfer_lib/nrd_xfer_effector.h"
77 # include "native_client/intermodule_comm/nacl_imc_c.h"
79 * In trusted code we use a NaClDesc to describe the IMC channel.
80 * It is this difference between trusted and untrusted code that motivated
81 * creating a type name.
83 typedef struct NaClDesc* NaClSrpcImcDescType;
84 #endif
85 #include <stdio.h>
87 EXTERN_C_BEGIN
89 /**
90 * Result codes to be returned from Simple RPC services.
92 typedef enum NaClSrpcResultCodes {
93 /** Invocation was successful. */
94 NACL_SRPC_RESULT_OK = 256,
95 /** Invocation was successful, exit the server dispatch loop.
96 * When returned from an RPC method, this causes the server to return
97 * NACL_SRPC_RESULT_OK and then exit the receive-dispatch-reply loop.
99 NACL_SRPC_RESULT_BREAK,
100 /** Some or all of a message was not received. */
101 NACL_SRPC_RESULT_MESSAGE_TRUNCATED,
102 /** The SRPC runtime system ran out of memory. */
103 NACL_SRPC_RESULT_NO_MEMORY,
104 /** The SRPC message layer detected a protocol version difference. */
105 NACL_SRPC_RESULT_PROTOCOL_MISMATCH,
106 /** The RPC number was not valid for any method. */
107 NACL_SRPC_RESULT_BAD_RPC_NUMBER,
108 /** An unknown type was passed to or returned from an RPC. */
109 NACL_SRPC_RESULT_BAD_ARG_TYPE,
110 /** Too few arguments were passed to or returned from an RPC. */
111 NACL_SRPC_RESULT_TOO_FEW_ARGS,
112 /** Too many arguments were passed to or returned from an RPC. */
113 NACL_SRPC_RESULT_TOO_MANY_ARGS,
114 /** One or more input argument types did not match the expected types. */
115 NACL_SRPC_RESULT_IN_ARG_TYPE_MISMATCH,
116 /** One or more output argument types did not match the expected types. */
117 NACL_SRPC_RESULT_OUT_ARG_TYPE_MISMATCH,
118 /** An unknown SRPC internal error occurred. */
119 NACL_SRPC_RESULT_INTERNAL,
120 /** The application signalled a generic error. */
121 NACL_SRPC_RESULT_APP_ERROR
122 } NaClSrpcError;
125 * Returns a descriptive string for the specified NaClSrpcError value.
126 * @param error_val A NaClSrpcError to be translated to a string.
127 * @return If error_val is valid, returns a string. Otherwise returns the
128 * string "Unrecognized NaClSrpcError value"
130 extern char* NaClSrpcErrorString(NaClSrpcError error_val);
133 * Type tag values for NaClSrpcArg unions.
135 enum NaClSrpcArgType {
136 NACL_SRPC_ARG_TYPE_INVALID = 'X', /**< invalid type */
137 NACL_SRPC_ARG_TYPE_BOOL = 'b', /**< scalar bool */
138 NACL_SRPC_ARG_TYPE_CHAR_ARRAY = 'C', /**< array of char */
139 NACL_SRPC_ARG_TYPE_DOUBLE = 'd', /**< scalar double */
140 NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY = 'D', /**< array of double */
141 NACL_SRPC_ARG_TYPE_HANDLE = 'h', /**< a descriptor (handle) */
142 NACL_SRPC_ARG_TYPE_INT = 'i', /**< scalar int */
143 NACL_SRPC_ARG_TYPE_INT_ARRAY = 'I', /**< array of int*/
144 NACL_SRPC_ARG_TYPE_STRING = 's', /**< NUL-terminated string */
145 NACL_SRPC_ARG_TYPE_OBJECT = 'o', /**< scriptable object*/
146 NACL_SRPC_ARG_TYPE_VARIANT_ARRAY = 'A' /**< array of NaClSrpcArg structs */
149 struct NaClSrpcVariantArray {
150 uint32_t count;
151 struct NaClSrpcArg *varr;
155 * Argument data type for passing arrays of char.
156 * @see NaClSrpcArg
158 struct NaClSrpcCharArray {
159 uint32_t count; /**< The number of characters in the array */
160 char *carr; /**< A chunk of memory containing "count" characters */
164 * Argument data type for passing arrays of int.
165 * @see NaClSrpcArg
167 struct NaClSrpcIntArray {
168 uint32_t count; /**< The number of integers in the array */
169 int *iarr; /**< A chunk of memory containing "count" integers */
173 * Argument data type for passing arrays of double.
174 * @see NaClSrpcArg
176 struct NaClSrpcDoubleArray {
177 uint32_t count; /**< The number of doubles in the array */
178 double *darr; /**< A chunk of memory containing "count" doubles */
182 * Used to convey parameters to and from RPC invocations. It is a variant
183 * type, with tag telling whether to treat the parameter as a bool or an
184 * array of characters, etc.
186 #ifdef __cplusplus
187 namespace nacl_srpc {
188 class ScriptableHandleBase;
190 #endif
192 struct NaClSrpcArg {
193 enum NaClSrpcArgType tag;
194 uint32_t reserved_pad;
196 * For efficiency, doubles should be 8-byte aligned so that
197 * loading them would require a single bus cycle, and arrays of
198 * NaClSrpcArgs will have to be 8-byte aligned as well, so it's
199 * either a 4 byte padding between the tag and the union or
200 * (implicitly) at the end. gcc does not (by default) enforce
201 * 8-byte alignment but visual studio does, so we explicitly pad
202 * so that both compilers will use the same memory layout, even if
203 * the gcc -malign-double flag were omitted.
205 union {
206 int bval;
207 int ival;
208 double dval;
209 struct NaClSrpcCharArray caval;
210 struct NaClSrpcIntArray iaval;
211 struct NaClSrpcDoubleArray daval;
212 char *sval;
213 NaClSrpcImcDescType hval;
214 /* object value that can be exported to the browser as is */
215 /* TODO - try to use a single type here */
216 #ifdef __cplusplus
217 nacl_srpc::ScriptableHandleBase *oval;
218 #else
219 void *oval;
220 #endif
221 struct NaClSrpcVariantArray vaval;
222 } u;
224 #ifndef __cplusplus
225 typedef struct NaClSrpcArg NaClSrpcArg;
226 #endif
228 /* TODO - duplicate string? */
229 #define STRINGZ_TO_SRPCARG(val, arg) do { \
230 (arg).tag = NACL_SRPC_ARG_TYPE_STRING; \
231 (arg).u.sval = (val); } while(0)
234 * The maximum number of arguments per SRPC routine.
236 #define NACL_SRPC_MAX_ARGS 128
239 * The maximum number of characters returnable from service discovery.
241 #define NACL_SRPC_MAX_SERVICE_DISCOVERY_CHARS 4000
243 /* A pointer to an SRPC channel data structure. */
244 typedef struct NaClSrpcChannel *NaClSrpcChannelPtr;
247 * Binaries that implement SRPC methods (servers) describe their services
248 * using these structures. These are converted into NaClSrpcDescs by the
249 * server constructor. They are also used when service discovery is done.
251 struct NaClSrpcHandlerDesc {
252 char const *entry_fmt; /**< a string containing
253 "name:input_types:output_types" */
254 int (*handler)(NaClSrpcChannelPtr channel,
255 NaClSrpcArg **in_args,
256 NaClSrpcArg **out_args); /**< function pointer
257 used to process calls
258 to the named method */
260 #ifndef __cplusplus
261 typedef struct NaClSrpcHandlerDesc NaClSrpcHandlerDesc;
262 #endif
265 * Used by clients to retain method name and type information.
267 struct NaClSrpcDesc {
268 char const *rpc_name; /**< string containing the method name*/
269 char const *in_args; /**< string containing the method input types */
270 char const *out_args; /**< string containing the method output types */
271 int (*handler)(NaClSrpcChannelPtr channel,
272 NaClSrpcArg **in_args,
273 NaClSrpcArg **out_args); /**< function pointer
274 used to process calls
275 to the named method */
277 #ifndef __cplusplus
278 typedef struct NaClSrpcDesc NaClSrpcDesc;
279 #endif
282 * The structure used to provide a buffering layer over the IMC.
284 struct NaClSrpcImcBuffer {
285 struct NaClImcMsgIoVec iovec[1]; /**< IMC message descriptor */
286 #ifdef __native_client__
287 struct NaClImcMsgHdr header; /**< IMC message header */
288 unsigned char bytes[IMC_USER_BYTES_MAX]; /**< character array
289 containing the
290 data to be sent
291 or received */
292 NaClSrpcImcDescType descs[IMC_USER_DESC_MAX]; /**< array of
293 descriptors to
294 be sent or
295 received */
296 #else
297 struct NaClImcTypedMsgHdr header;
298 unsigned char bytes[NACL_ABI_IMC_USER_BYTES_MAX];
299 NaClSrpcImcDescType descs[NACL_ABI_IMC_USER_DESC_MAX];
300 #endif
301 uint32_t next_desc; /**< index into "bytes" of the next
302 descriptor to be read or written */
303 size_t next_byte; /**< index into "bytes" of the next
304 data byte to be read or written */
305 size_t last_byte; /**< index into "bytes" of the last
306 data byte to be read or written */
308 #ifndef __cplusplus
310 * A typedef for struct NaClSrpcImcBuffer for use in C.
312 typedef struct NaClSrpcImcBuffer NaClSrpcImcBuffer;
313 #endif
316 * The encapsulation of all the data necessary for an RPC connection,
317 * either client or server.
319 struct NaClSrpcChannel {
320 NaClSrpcImcDescType imc_handle;
321 #ifndef __native_client__
322 struct NaClNrdXferEffector eff;
323 #endif
324 NaClSrpcImcBuffer send_buf;
325 NaClSrpcImcBuffer receive_buf;
326 NaClSrpcDesc* rpc_descr;
327 uint32_t rpc_count;
328 void *server_instance_data;
329 const char* service_string;
330 size_t service_string_length;
331 int timing_enabled;
332 double send_usec;
333 double receive_usec;
334 double imc_read_usec;
335 double imc_write_usec;
337 #ifndef __cplusplus
339 * A typedef for struct NaClSrpcChannel for use in C.
341 typedef struct NaClSrpcChannel NaClSrpcChannel;
342 #endif
345 * Constructs an SRPC client object communicating over an IMC descriptor.
346 * Clients issue RPC requests and receive responses.
347 * @param channel The channel descriptor to be constructed.
348 * @param imc_desc The NaClSrpcImcDescType describing the IMC channel to
349 * communicate over.
350 * @return On success, 1; on failure, 0.
352 int NaClSrpcClientCtor(NaClSrpcChannel *channel, NaClSrpcImcDescType imc_desc);
354 * Constructs an SRPC server object communicating over an IMC descriptor.
355 * Servers wait for RPC requests, dispatch them to implementations, and return
356 * responses.
357 * @param channel The channel descriptor to be constructed.
358 * @param imc_desc The NaClSrpcImcDescType describing the IMC channel to
359 * communicate over.
360 * @param handlers An array of NaClSrpcHandlerDesc structures describing the
361 * set of services handled by this server.
362 * @param instance_data A value to be stored on the channel descriptor
363 * for conveying data specific to this particular server instance.
364 * @return On success, 1; on failure, 0.
366 int NaClSrpcServerCtor(NaClSrpcChannel *channel,
367 NaClSrpcImcDescType imc_desc,
368 const NaClSrpcHandlerDesc *handlers,
369 void* instance_data);
371 * A utility function that creates a NaClSrpcImcDescType from the
372 * platform-defined NaClHandle type.
373 * @param handle The handle to be converted.
374 * @return On success, a valid NaClSrpcImcDescType. On failure, -1.
376 NaClSrpcImcDescType NaClSrpcImcDescTypeFromHandle(NaClHandle handle);
379 * Destroys the specified client or server channel.
380 * @param channel The channel to be destroyed.
382 void NaClSrpcDtor(NaClSrpcChannel *channel);
385 * Runs an SRPC receive-dispatch-respond loop on the specified socket
386 * descriptor.
387 * @param socket_desc A NaClHandle that RPCs will communicate over.
388 * @param methods An array of NaClSrpcHandlerDesc structures describing the
389 * set of services handled by this server.
390 * @param instance_data A value to be stored on the channel descriptor
391 * for conveying data specific to this particular server instance.
392 * @return On success, 1; on failure, 0.
394 int NaClSrpcServerLoop(NaClHandle socket_desc,
395 const struct NaClSrpcHandlerDesc methods[],
396 void *instance_data);
399 * Runs an SRPC receive-dispatch-respond loop on the specified
400 * NaClSrpcImcDescType object.
401 * @param imc_socket_desc A NaClSrpcImcDescType object that RPCs will
402 * communicate over.
403 * @param methods An array of NaClSrpcHandlerDesc structures
404 * describing the set of services handled by this server.
405 * @param instance_data A value to be stored on the channel
406 * descriptor for conveying data specific to this particular server
407 * instance.
408 * @return On success, 1; on failure, 0.
410 int NaClSrpcServerLoopImcDesc(NaClSrpcImcDescType imc_socket_desc,
411 const struct NaClSrpcHandlerDesc methods[],
412 void *instance_data);
414 #ifdef __native_client__
416 * Runs an SRPC receive-dispatch-respond loop on the "default" descriptor.
417 * NaCl modules are started with a default descriptor (obtained by an accept
418 * call on the bound socket created by the service runtime). The methods
419 * exported are those using the NACL_SRPC_METHOD macro in the source of the
420 * module, plus the implicitly defined methods.
421 * @param instance_data A value to be stored on the channel descriptor
422 * for conveying data specific to this particular server instance.
423 * @return On success, 1; on failure, 0.
425 int NaClSrpcDefaultServerLoop(void *instance_data);
426 #endif /* __native_client__ */
429 * Prints the methods available from the specified channel to stdout. For
430 * services, the method list is the table specified when the
431 * NaClSrpcServerCtor was invoked. For clients, it is set by the initial
432 * call to the implicit service_discovery method.
433 * @param channel A channel descriptor.
435 void NaClSrpcDumpInterfaceDesc(const NaClSrpcChannel *channel);
437 * Obtains the index of the specified RPC name.
438 * @param channel The channel descriptor to be searched.
439 * @param name The exported name of the method.
440 * @return A non-negative index if the name was found in the channel's set of
441 * methods. If the name was not found, it returns -1.
443 int NaClSrpcGetRpcNum(const NaClSrpcChannel *channel, char const *name);
445 #ifdef __native_client__
447 * Not documented: in Native Client code the default RPC descriptors are
448 * recorded in a special section, ".nacl_rpc_methods".
449 * The handler array begins at __kNaclSrpcHandlers.
451 extern const struct NaClSrpcHandlerDesc
452 __attribute__ ((section (".nacl_rpc_methods")))
453 __attribute__ ((aligned (8)))
454 __kNaClSrpcHandlers[];
456 * Not documented: in NativeClient code the default RPC descriptors are
457 * recorded in a special section, ".nacl_rpc_methods".
458 * The handler array ends at __kNaclSrpcHandlerEnd.
460 extern const struct NaClSrpcHandlerDesc
461 __attribute__ ((section (".nacl_rpc_methods")))
462 __attribute__ ((aligned (8)))
463 __kNaClSrpcHandlerEnd;
465 * Exports a method to the default RPC descriptor array.
466 * @param entry_format a string with the format "x:y:z", where x is the method
467 * name, * y is the parameter type list, and z is the return value type list.
468 * @param method_handler A function pointer for the implementation of the
469 * method.
471 #define NACL_SRPC_METHOD(entry_format, method_handler) \
472 struct NaClSrpcHandlerDesc \
473 __attribute__ ((section (".nacl_rpc_methods"))) \
474 __attribute__ ((aligned (8))) \
475 NaClSrpcMethod##method_handler = \
476 { entry_format, method_handler }
478 #endif /* defined(NACL_LINUX) ... */
481 * @clientSrpc Invokes a specified RPC on the given channel. Parameters
482 * are passed by stdarg conventions and determined from the types specified
483 * in the method tables.
484 * @param channel The channel descriptor to use to invoke the RPC.
485 * @param rpc_name The name of the RPC to be invoked.
486 * @return A NaClSrpcResultCodes indicating success (NACL_SRPC_RESULT_OK)
487 * or failure.
488 * @see NaClSrpcResultCodes
490 extern NaClSrpcError NaClSrpcInvokeByName(NaClSrpcChannel *channel,
491 const char *rpc_name,
492 ...);
494 * @clientSrpc Invokes a specified RPC on the given channel. Parameters
495 * are passed by stdarg conventions and determined from the types specified
496 * in the method tables stored in channel.
497 * @param channel The channel descriptor to use to invoke the RPC.
498 * @param rpc_num The index of the RPC to be invoked.
499 * @return A NaClSrpcResultCodes indicating success (NACL_SRPC_RESULT_OK)
500 * or failure.
501 * @see NaClSrpcResultCodes
503 extern NaClSrpcError NaClSrpcInvoke(NaClSrpcChannel *channel,
504 uint32_t rpc_num,
505 ...);
507 * @clientSrpc Invokes a specified RPC on the given channel. Parameters are
508 * passed in arrays and are type-checked against the types specified in the
509 * method tables stored in channel.
510 * @param channel The channel descriptor to use to invoke the RPC.
511 * @param rpc_num The index of the RPC to be invoked.
512 * @param args The array of parameter pointers to arguments to be passed in.
513 * @param rets The array of parameter pointers to arguments to be returned.
514 * @return A NaClSrpcResultCodes indicating success (NACL_SRPC_RESULT_OK)
515 * or failure.
516 * @see NaClSrpcResultCodes
518 extern NaClSrpcError NaClSrpcInvokeV(NaClSrpcChannel *channel,
519 uint32_t rpc_num,
520 NaClSrpcArg *args[],
521 NaClSrpcArg *rets[]);
523 * @clientSrpc Invokes a specified RPC on the given channel. Parameters are
524 * passed in and returned through pointers to stdargs. They are type-checked
525 * against the types specified in the method tables stored in channel.
526 * @param channel The channel descriptor to use to invoke the RPC.
527 * @param rpc_num The index of the RPC to be invoked.
528 * @param in_va The pointer to stdargs list of arguments to be passed in.
529 * @param out_va The pointer to stdargs list of arguments to be returned.
530 * @return A NaClSrpcResultCodes indicating success (NACL_SRPC_RESULT_OK)
531 * or failure.
532 * @see NaClSrpcResultCodes
534 extern NaClSrpcError NaClSrpcInvokeVaList(NaClSrpcChannel *channel,
535 uint32_t rpc_num,
536 va_list in_va,
537 va_list out_va);
540 * @serverSrpc Receives an RPC request, invokes the corresponding method
541 * from the table in the channel, and returns the result.
542 * @param channel The channel descriptor to use to invoke the RPC.
543 * @return A NaClSrpcResultCodes indicating success (NACL_SRPC_RESULT_OK)
544 * or failure.
545 * @see NaClSrpcResultCodes
547 NaClSrpcError NaClSrpcReceiveAndDispatch(NaClSrpcChannel *channel);
550 * @eitherSrpc Enables or disables timing of the specified channel.
551 * @param channel The channel descriptor whose timing to consult.
552 * @param enable_timing If zero, disable timing. Otherwise, enable timing.
553 * @see NaClSrpcGetTimes()
555 void NaClSrpcToggleChannelTiming(NaClSrpcChannel* channel, int enable_timing);
557 * @eitherSrpc Gathers the microsecond-granularity timing results retained
558 * for the specified channel. If timing is not enabled, this function sets
559 * all _time parameters to 0.0.
560 * @param channel A channel descriptor.
561 * @param send_time The time spent in sending via this channel.
562 * @param receive_time The time spent in receiving via this channel.
563 * @param imc_read_time The time spent waiting for IMC layer reads via
564 * this channel.
565 * @param imc_write_time The time spent waiting for IMC layer writes via
566 * this channel.
567 * @see NaclSrpcToggleChannelTiming()
569 void NaClSrpcGetTimes(NaClSrpcChannel *channel,
570 double *send_time,
571 double *receive_time,
572 double *imc_read_time,
573 double *imc_write_time);
576 * @serverSrpc Initializes the SRPC system, setting up the command channel
577 * and preparing the graphics subsystem for embedding in the browser.
579 void srpc_init();
582 * RPC number for "implicit" timing method.
584 #define NACL_SRPC_GET_TIMES_METHOD 0xfffffffe
586 * RPC number for "implicit" timing control method.
588 #define NACL_SRPC_TOGGLE_CHANNEL_TIMING_METHOD 0xfffffffd
590 EXTERN_C_END
593 * @}
594 * End of System Calls group
597 #endif /* NATIVE_CLIENT_TOOLS_LIBSRPC_NACL_SRPC_H_ */