IPCMechanism.h

Go to the documentation of this file.
00001 
00106     bcTRANSACTION,
00107     bcREPLY,
00108     /*
00109         binder_transaction_data: the sent command.
00110     */
00111     
00112     bcACQUIRE_RESULT,
00113     /*
00114         int32:  0 if the last brATTEMPT_ACQUIRE was not successful.
00115         Else you have acquired a primary reference on the object.
00116     */
00117     
00118     bcFREE_BUFFER,
00119     /*
00120         void *: ptr to transaction data received on a read
00121     */
00122     
00123     bcINCREFS,
00124     bcACQUIRE,
00125     bcRELEASE,
00126     bcDECREFS,
00127     /*
00128         int32:  descriptor
00129     */
00130     
00131     bcATTEMPT_ACQUIRE,
00132     /*
00133         int32:  priority
00134         int32:  descriptor
00135     */
00136     
00137     bcRESUME_THREAD,
00138     /*
00139         int32:  thread ID
00140     */
00141     
00142     bcSET_THREAD_ENTRY,
00143     /*
00144         void *: thread entry function for new threads created to handle tasks
00145         void *: argument passed to those threads
00146     */
00147     
00148     bcREGISTER_LOOPER,
00149     /*
00150         No parameters.
00151         Register a spawned looper thread with the device.  This must be
00152         called by the function that is supplied in bcSET_THREAD_ENTRY as
00153         part of its initialization with the binder.
00154     */
00155     
00156     bcENTER_LOOPER,
00157     bcEXIT_LOOPER,
00158     /*
00159         No parameters.
00160         These two commands are sent as an application-level thread
00161         enters and exits the binder loop, respectively.  They are
00162         used so the binder can have an accurate count of the number
00163         of looping threads it has available.
00164     */
00165     
00166     bcCATCH_ROOT_OBJECTS,
00167     /*
00168         No parameters.
00169         Call this to have your team start catching root objects
00170         published by other teams that are spawned outside of the binder.
00171         When this happens, you will receive a brTRANSACTION with the
00172         tfRootObject flag set.  (Note that this is distinct from receiving
00173         normal root objects, which are a brREPLY.)
00174     */
00175     
00176     bcKILL_TEAM
00177     /*
00178         No parameters.
00179         Simulate death of a kernel team.  For debugging only.
00180     */
00181 };
00182 @endcode
00183 
00184 The most interesting commands here are bcTRANSACTION and bcREPLY, which
00185 initiate an IPC transaction and return a reply for a transaction,
00186 respectively.  The data structure following these commands is:
00187 
00188 @code
00189 enum transaction_flags {
00190     tfInline = 0x01,            // not yet implemented
00191     tfRootObject = 0x04,        // contents are the component's root object
00192     tfStatusCode = 0x08         // contents are a 32-bit status code
00193 };
00194 
00195 struct binder_transaction_data
00196 {
00197     // The first two are only used for bcTRANSACTION and brTRANSACTION,
00198     // identifying the target and contents of the transaction.
00199     union {
00200         size_t  handle;     // target descriptor of command transaction
00201         void    *ptr;       // target descriptor of return transaction
00202     } target;
00203     uint32  code;           // transaction command
00204     
00205     // General information about the transaction.
00206     uint32  flags;
00207     int32   priority;       // requested/current thread priority
00208     size_t  data_size;      // number of bytes of data
00209     size_t  offsets_size;   // number of bytes of object offsets
00210     
00211     // If this transaction is inline, the data immediately
00212     // follows here; otherwise, it ends with a pointer to
00213     // the data buffer.
00214     union {
00215         struct {
00216             const void  *buffer;    // transaction data
00217             const void  *offsets;   // binder object offsets
00218         } ptr;
00219         uint8   buf[8];
00220     } data;
00221 };
00222 @endcode
00223 
00224 Thus, to initiate an IPC transaction, you will essentially perform a
00225 BINDER_READ_WRITE ioctl with the write buffer containing bcTRANSACTION
00226 follewed by a binder_transaction_data.  In this structure @e target is
00227 the handle of the object that should receive the transaction (we'll talk
00228 about handles later), @e code tells the object what to do when it
00229 receives the transaction, @e priority is the thread priority to run the
00230 IPC at, and there is a @e data buffer containing the transaction data,
00231 as well as an (optional) additional @e offsets buffer of meta-data.
00232 
00233 Given the @e target handle, the driver determines which process that
00234 object lives in and dispatches this transaction to one of the waiting
00235 threads in its thread pool (spawning a new thread if needed).  That
00236 thread is waiting in a BINDER_WRITE_READ ioctl() to the driver, and so
00237 returns with its read buffer filled in with the commands it needs to
00238 execute.  These commands a very similar to the write commands, for the
00239 most part corresponding to write operations on the other side:
00240 
00241 @code
00242 enum BinderDriverReturnProtocol {
00243     brERROR = -1,
00244     /*
00245         int32: error code
00246     */
00247     
00248     brOK = 0,
00249     brTIMEOUT,
00250     brWAKEUP,
00251     /*  No parameters! */
00252     
00253     brTRANSACTION,
00254     brREPLY,
00255     /*
00256         binder_transaction_data: the received command.
00257     */
00258     
00259     brACQUIRE_RESULT,
00260     /*
00261         int32: 0 if the last bcATTEMPT_ACQUIRE was not successful.
00262         Else the remote object has acquired a primary reference.
00263     */
00264     
00265     brDEAD_REPLY,
00266     /*
00267         The target of the last transaction (either a bcTRANSACTION or
00268         a bcATTEMPT_ACQUIRE) is no longer with us.  No parameters.
00269     */
00270     
00271     brTRANSACTION_COMPLETE,
00272     /*
00273         No parameters... always refers to the last transaction requested
00274         (including replies).  Note that this will be sent even for asynchronous
00275         transactions.
00276     */
00277     
00278     brINCREFS,
00279     brACQUIRE,
00280     brRELEASE,
00281     brDECREFS,
00282     /*
00283         void *: ptr to binder
00284     */
00285     
00286     brATTEMPT_ACQUIRE,
00287     /*
00288         int32:  priority
00289         void *: ptr to binder
00290     */
00291     
00292     brEVENT_OCCURRED,
00293     /*
00294         This is returned when the bcSET_NEXT_EVENT_TIME has elapsed.
00295         At this point the next event time is set to B_INFINITE_TIMEOUT,
00296         so you must send another bcSET_NEXT_EVENT_TIME command if you
00297         have another event pending.
00298     */
00299     
00300     brFINISHED
00301 };
00302 @endcode
00303 
00304 Continuing our example, the receiving thread will come back with a
00305 brTRANSACTION command at the end of its buffer.  This command uses the
00306 same binder_transaction_data structure that was used to send the data,
00307 basically containing the same information that was sent but now available
00308 in the local process space.
00309 
00310 The recipient, in user space will then hand this transaction over to the
00311 target object for it to execute and return its result.  Upon getting the
00312 result, a new write buffer is created containing the bcREPLY reply
00313 command with a binder_transaction_data structure containing the resulting
00314 data.  This is returned with a BINDER_WRITE_READ ioctl() on the driver,
00315 sending the reply back to the original process and leaving the thread
00316 waiting for the next transaction to perform.
00317 
00318 The original thread finally returns back from its own BINDER_WRITE_READ
00319 with a brREPLY command containing the reply data.
00320 
00321 Note that the original thread may also receive brTRANSACTION commands while
00322 it is waiting for a reply.  This represents a recursion across processes —
00323 the receiving thread making a call on to an object back in the original
00324 process.  It is the responsibility of the driver to keep track of all
00325 active transactions, so it can dispatch transactions to the correct thread
00326 when recursion happens.
00327 
00328 @subsection ObjectMappingAndReferencing Object Mapping and Referencing
00329 
00330 One of the important responsibilities of the driver is to perform mapping
00331 of objects from one process to another.  This is key to both the
00332 communication mechanism (targetting and referencing objects) as well as
00333 the capability model (only allowing a particular process to perform
00334 operations on remote objects that it has been explicitly given knowledge
00335 about).
00336 
00337 There are two distinct forms of an object reference: as an address in a
00338 processes's memory space, or as an abstract 32-bit handle.  These
00339 representations are mutually exclusive: @b all references in a process
00340 to objects local to that process are in the form of an address, while
00341 all references to objects in another process are always in the form of
00342 a handle.
00343 
00344 For example, note the @e target field of binder_transaction_data.  When
00345 sending a transaction, this contains a handle to the destination object
00346 (because you always send transactions to other processes).  The recipient
00347 of the transaction, however, sees this as a point to the object in its
00348 local address space.  The driver maintains mappings of pointers and
00349 handles between processes so that it can perform this translation.
00350 
00351 We also must be able to send references to objects through transactions.
00352 This is done by placing the object reference (either a local pointer or
00353 remote handle) in to the transaction buffer.  The driver must translate
00354 this reference to the corresponding reference in the receiving process,
00355 however, just like we do with the transaction target.
00356 
00357 In order to do reference translation, the driver needs to know where these
00358 references appear in the transaction data.  This is where the additional
00359 @e offsets buffer comes in.  It contains of a series of indicies into the
00360 data buffer, describing where objects appear.  The driver can then rewrite
00361 the buffer data, translating each of those objects from the sending
00362 process reference to the correct reference in the receiving process.
00363 
00364 Note that the driver does not know anything about a particular Binder
00365 object until that object is sent through the driver to another process.
00366 At that point the driver adds the object's address to its mapping table
00367 and asks the owning process to hold a reference on it.  When no other
00368 processes know about the object, it is removed from the mapping table
00369 and its owning process is told to release the driver's reference.  This
00370 avoids maintaining the (relatively significant) driver state for an
00371 object as long as it is only used in its local process.
00372 */