1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIB_FIDL_BIND_H_ 6 #define LIB_FIDL_BIND_H_ 7 8 #include <lib/async/dispatcher.h> 9 #include <zircon/fidl.h> 10 11 __BEGIN_CDECLS 12 13 // A generic FIDL dispatch function. 14 // 15 // For FIDL interfaces with [Layout="Simple"], the C backend generates a 16 // dispatch function that decodes the |msg| and calls through an |ops| table. 17 // 18 // This function signature matches the structure of these generated functions 19 // but with the type of the |ops| table erased. 20 // 21 // Example: 22 // 23 // fidl_bind(dispacher, channel, (fidl_dispatch_t*)spaceship_SpaceShip_dispatch, ctx, &kOps); 24 // 25 typedef zx_status_t(fidl_dispatch_t)(void* ctx, fidl_txn_t* txn, 26 fidl_msg_t* msg, const void* ops); 27 28 // Binds a |dispatch| function to channel| using |dispatcher|. 29 // 30 // This function adds an |async_wait_t| to the given |dispatcher| that waits 31 // asynchronously for new messages to arrive on |channel|. When a message 32 // arrives, the |dispatch| function is called on one of the threads associated 33 // with the |dispatcher| with the |fidl_msg_t| as well as the given |ctx| and 34 // |ops|. 35 // 36 // Typically, the |dispatch| function is generated by the C backend for FIDL 37 // interfaces with with [Layout="Simple"] (see |fidl_dispatch_t|). These 38 // dispatch functions decode the |fidl_msg_t| and call through the |ops| table 39 // implementations of the interface's methods, passing along the |ctx| and a 40 // |fidl_txn_t| (if the method has a reply message). 41 // 42 // The |fidl_txn_t| passed to |dispatch| is valid only until |dispatch| returns. 43 // If the method has a reply message, the |reply| function on the |fidl_txn_t| 44 // object must be called synchronously within the |dispatch| call. 45 // 46 // If a client wishes to reply to the message asynchronously, |fidl_async_txn_create| 47 // must be invoked on |fidl_txn_t|, and ZX_ERR_ASYNC must be returned. 48 // 49 // Returns whether |fidl_bind| was able to begin waiting on the given |channel|. 50 // Upon any error, |channel| is closed and the binding is terminated. Shutting down 51 // the |dispatcher| also results in |channel| being closed. 52 // 53 // It is safe to shutdown the dispatcher at any time. 54 // 55 // It is unsafe to destroy the dispatcher from within a dispatch function. 56 // It is unsafe to destroy the dispatcher while any |fidl_async_txn_t| objects 57 // are alive. 58 zx_status_t fidl_bind(async_dispatcher_t* dispatcher, zx_handle_t channel, 59 fidl_dispatch_t* dispatch, void* ctx, const void* ops); 60 61 // An asynchronous FIDL txn. 62 // 63 // This is an opaque wrapper around |fidl_txn_t| which can extend the lifetime 64 // of the object beyond the dispatched function. 65 typedef struct fidl_async_txn fidl_async_txn_t; 66 67 // Takes ownership of |txn| and allows usage of the txn beyond the currently 68 // dispatched function. 69 // 70 // If this function is invoked within a dispatched function, that function 71 // must return ZX_ERR_ASYNC. 72 // 73 // The result must be destroyed with a call to |fidl_async_txn_complete|. 74 fidl_async_txn_t* fidl_async_txn_create(fidl_txn_t* txn); 75 76 // Acquire a reference to the |fidl_txn_t| backing this txn object. 77 // 78 // It is unsafe to use this |fidl_txn_t| after |async_txn| is completed. 79 fidl_txn_t* fidl_async_txn_borrow(fidl_async_txn_t* async_txn); 80 81 // Destroys an asynchronous transaction created with |fidl_async_txn_create|. 82 // 83 // If requested, rebinds the underlying txn against the binding. 84 // Returns an error if |rebind| is true and the transaction could not be 85 // re-bound. 86 // 87 // In all cases, the |async_txn| object is consumed. 88 zx_status_t fidl_async_txn_complete(fidl_async_txn_t* async_txn, bool rebind); 89 90 __END_CDECLS 91 92 #endif // LIB_FIDL_BIND_H_ 93