1 // Copyright 2014 The Chromium 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 package org.chromium.mojo.system.impl; 6 7 import org.chromium.base.CalledByNative; 8 import org.chromium.base.JNINamespace; 9 import org.chromium.mojo.system.AsyncWaiter; 10 import org.chromium.mojo.system.Core; 11 import org.chromium.mojo.system.DataPipe; 12 import org.chromium.mojo.system.DataPipe.ConsumerHandle; 13 import org.chromium.mojo.system.DataPipe.ProducerHandle; 14 import org.chromium.mojo.system.Handle; 15 import org.chromium.mojo.system.MessagePipeHandle; 16 import org.chromium.mojo.system.MojoException; 17 import org.chromium.mojo.system.MojoResult; 18 import org.chromium.mojo.system.Pair; 19 import org.chromium.mojo.system.SharedBufferHandle; 20 import org.chromium.mojo.system.SharedBufferHandle.DuplicateOptions; 21 import org.chromium.mojo.system.SharedBufferHandle.MapFlags; 22 import org.chromium.mojo.system.UntypedHandle; 23 24 import java.nio.ByteBuffer; 25 import java.nio.ByteOrder; 26 import java.util.ArrayList; 27 import java.util.List; 28 29 /** 30 * Implementation of {@link Core}. 31 */ 32 @JNINamespace("mojo::android") 33 public class CoreImpl implements Core, AsyncWaiter { 34 35 /** 36 * Discard flag for the |MojoReadData| operation. 37 */ 38 private static final int MOJO_READ_DATA_FLAG_DISCARD = 1 << 1; 39 40 /** 41 * the size of a handle, in bytes. 42 */ 43 private static final int HANDLE_SIZE = 4; 44 45 /** 46 * the size of a flag, in bytes. 47 */ 48 private static final int FLAG_SIZE = 4; 49 50 /** 51 * The mojo handle for an invalid handle. 52 */ 53 static final int INVALID_HANDLE = 0; 54 55 private static class LazyHolder { 56 private static final Core INSTANCE = new CoreImpl(); 57 } 58 59 /** 60 * @return the instance. 61 */ getInstance()62 public static Core getInstance() { 63 return LazyHolder.INSTANCE; 64 } 65 CoreImpl()66 private CoreImpl() { 67 } 68 69 /** 70 * @see Core#getTimeTicksNow() 71 */ 72 @Override getTimeTicksNow()73 public long getTimeTicksNow() { 74 return nativeGetTimeTicksNow(); 75 } 76 77 /** 78 * @see Core#waitMany(List, long) 79 */ 80 @Override waitMany(List<Pair<Handle, HandleSignals>> handles, long deadline)81 public WaitManyResult waitMany(List<Pair<Handle, HandleSignals>> handles, long deadline) { 82 // Allocate a direct buffer to allow native code not to reach back to java. Buffer will 83 // contain all mojo handles, followed by all flags values. 84 ByteBuffer buffer = allocateDirectBuffer(handles.size() * 8); 85 int index = 0; 86 for (Pair<Handle, HandleSignals> handle : handles) { 87 buffer.putInt(HANDLE_SIZE * index, getMojoHandle(handle.first)); 88 buffer.putInt(HANDLE_SIZE * handles.size() + FLAG_SIZE * index, 89 handle.second.getFlags()); 90 index++; 91 } 92 int code = nativeWaitMany(buffer, deadline); 93 WaitManyResult result = new WaitManyResult(); 94 // If result is greater than 0, result is the indexed of the available handle. To make sure 95 // it cannot be misinterpreted, set handleIndex to a negative number in case of error. 96 result.setHandleIndex(code); 97 result.setMojoResult(filterMojoResultForWait(code)); 98 return result; 99 } 100 101 /** 102 * @see Core#wait(Handle, HandleSignals, long) 103 */ 104 @Override wait(Handle handle, HandleSignals signals, long deadline)105 public int wait(Handle handle, HandleSignals signals, long deadline) { 106 return filterMojoResultForWait(nativeWait(getMojoHandle(handle), 107 signals.getFlags(), deadline)); 108 } 109 110 /** 111 * @see Core#createMessagePipe(MessagePipeHandle.CreateOptions) 112 */ 113 @Override createMessagePipe( MessagePipeHandle.CreateOptions options)114 public Pair<MessagePipeHandle, MessagePipeHandle> createMessagePipe( 115 MessagePipeHandle.CreateOptions options) { 116 ByteBuffer optionsBuffer = null; 117 if (options != null) { 118 optionsBuffer = allocateDirectBuffer(8); 119 optionsBuffer.putInt(0, 8); 120 optionsBuffer.putInt(4, options.getFlags().getFlags()); 121 } 122 NativeCreationResult result = nativeCreateMessagePipe(optionsBuffer); 123 if (result.getMojoResult() != MojoResult.OK) { 124 throw new MojoException(result.getMojoResult()); 125 } 126 return Pair.<MessagePipeHandle, MessagePipeHandle> create( 127 new MessagePipeHandleImpl(this, result.getMojoHandle1()), 128 new MessagePipeHandleImpl(this, result.getMojoHandle2())); 129 } 130 131 /** 132 * @see Core#createDataPipe(DataPipe.CreateOptions) 133 */ 134 @Override createDataPipe(DataPipe.CreateOptions options)135 public Pair<ProducerHandle, ConsumerHandle> createDataPipe(DataPipe.CreateOptions options) { 136 ByteBuffer optionsBuffer = null; 137 if (options != null) { 138 optionsBuffer = allocateDirectBuffer(16); 139 optionsBuffer.putInt(0, 16); 140 optionsBuffer.putInt(4, options.getFlags().getFlags()); 141 optionsBuffer.putInt(8, options.getElementNumBytes()); 142 optionsBuffer.putInt(12, options.getCapacityNumBytes()); 143 } 144 NativeCreationResult result = nativeCreateDataPipe(optionsBuffer); 145 if (result.getMojoResult() != MojoResult.OK) { 146 throw new MojoException(result.getMojoResult()); 147 } 148 return Pair.<ProducerHandle, ConsumerHandle> create( 149 new DataPipeProducerHandleImpl(this, result.getMojoHandle1()), 150 new DataPipeConsumerHandleImpl(this, result.getMojoHandle2())); 151 } 152 153 /** 154 * @see Core#createSharedBuffer(SharedBufferHandle.CreateOptions, long) 155 */ 156 @Override createSharedBuffer( SharedBufferHandle.CreateOptions options, long numBytes)157 public SharedBufferHandle createSharedBuffer( 158 SharedBufferHandle.CreateOptions options, long numBytes) { 159 ByteBuffer optionsBuffer = null; 160 if (options != null) { 161 optionsBuffer = allocateDirectBuffer(8); 162 optionsBuffer.putInt(0, 8); 163 optionsBuffer.putInt(4, options.getFlags().getFlags()); 164 } 165 NativeCreationResult result = nativeCreateSharedBuffer(optionsBuffer, numBytes); 166 if (result.getMojoResult() != MojoResult.OK) { 167 throw new MojoException(result.getMojoResult()); 168 } 169 assert result.getMojoHandle2() == 0; 170 return new SharedBufferHandleImpl(this, result.getMojoHandle1()); 171 } 172 173 /** 174 * @see org.chromium.mojo.system.Core#acquireNativeHandle(int) 175 */ 176 @Override acquireNativeHandle(int handle)177 public UntypedHandle acquireNativeHandle(int handle) { 178 return new UntypedHandleImpl(this, handle); 179 } 180 181 /** 182 * @see Core#getDefaultAsyncWaiter() 183 */ 184 @Override getDefaultAsyncWaiter()185 public AsyncWaiter getDefaultAsyncWaiter() { 186 return this; 187 } 188 189 /** 190 * @see AsyncWaiter#asyncWait(Handle, Core.HandleSignals, long, Callback) 191 */ 192 @Override asyncWait(Handle handle, HandleSignals signals, long deadline, Callback callback)193 public Cancellable asyncWait(Handle handle, HandleSignals signals, long deadline, 194 Callback callback) { 195 return nativeAsyncWait(getMojoHandle(handle), signals.getFlags(), deadline, callback); 196 } 197 closeWithResult(int mojoHandle)198 int closeWithResult(int mojoHandle) { 199 return nativeClose(mojoHandle); 200 } 201 close(int mojoHandle)202 void close(int mojoHandle) { 203 int mojoResult = nativeClose(mojoHandle); 204 if (mojoResult != MojoResult.OK) { 205 throw new MojoException(mojoResult); 206 } 207 } 208 209 /** 210 * @see MessagePipeHandle#writeMessage(ByteBuffer, List, MessagePipeHandle.WriteFlags) 211 */ writeMessage(MessagePipeHandleImpl pipeHandle, ByteBuffer bytes, List<? extends Handle> handles, MessagePipeHandle.WriteFlags flags)212 void writeMessage(MessagePipeHandleImpl pipeHandle, ByteBuffer bytes, 213 List<? extends Handle> handles, MessagePipeHandle.WriteFlags flags) { 214 ByteBuffer handlesBuffer = null; 215 if (handles != null && !handles.isEmpty()) { 216 handlesBuffer = allocateDirectBuffer(handles.size() * HANDLE_SIZE); 217 for (Handle handle : handles) { 218 handlesBuffer.putInt(getMojoHandle(handle)); 219 } 220 handlesBuffer.position(0); 221 } 222 int mojoResult = nativeWriteMessage(pipeHandle.getMojoHandle(), bytes, 223 bytes == null ? 0 : bytes.limit(), handlesBuffer, 224 flags.getFlags()); 225 if (mojoResult != MojoResult.OK) { 226 throw new MojoException(mojoResult); 227 } 228 // Success means the handles have been invalidated. 229 if (handles != null) { 230 for (Handle handle : handles) { 231 if (handle.isValid()) { 232 ((HandleBase) handle).invalidateHandle(); 233 } 234 } 235 } 236 } 237 238 /** 239 * @see MessagePipeHandle#readMessage(ByteBuffer, int, MessagePipeHandle.ReadFlags) 240 */ readMessage(MessagePipeHandleImpl handle, ByteBuffer bytes, int maxNumberOfHandles, MessagePipeHandle.ReadFlags flags)241 MessagePipeHandle.ReadMessageResult readMessage(MessagePipeHandleImpl handle, 242 ByteBuffer bytes, int maxNumberOfHandles, 243 MessagePipeHandle.ReadFlags flags) { 244 ByteBuffer handlesBuffer = null; 245 if (maxNumberOfHandles > 0) { 246 handlesBuffer = allocateDirectBuffer(maxNumberOfHandles * HANDLE_SIZE); 247 } 248 MessagePipeHandle.ReadMessageResult result = nativeReadMessage( 249 handle.getMojoHandle(), bytes, handlesBuffer, flags.getFlags()); 250 if (result.getMojoResult() != MojoResult.OK && 251 result.getMojoResult() != MojoResult.RESOURCE_EXHAUSTED && 252 result.getMojoResult() != MojoResult.SHOULD_WAIT) { 253 throw new MojoException(result.getMojoResult()); 254 } 255 256 if (result.getMojoResult() == MojoResult.OK) { 257 if (bytes != null) { 258 bytes.position(0); 259 bytes.limit(result.getMessageSize()); 260 } 261 262 List<UntypedHandle> handles = new ArrayList<UntypedHandle>( 263 result.getHandlesCount()); 264 for (int i = 0; i < result.getHandlesCount(); ++i) { 265 int mojoHandle = handlesBuffer.getInt(HANDLE_SIZE * i); 266 handles.add(new UntypedHandleImpl(this, mojoHandle)); 267 } 268 result.setHandles(handles); 269 } 270 return result; 271 } 272 273 /** 274 * @see ConsumerHandle#discardData(int, DataPipe.ReadFlags) 275 */ discardData(DataPipeConsumerHandleImpl handle, int numBytes, DataPipe.ReadFlags flags)276 int discardData(DataPipeConsumerHandleImpl handle, int numBytes, 277 DataPipe.ReadFlags flags) { 278 int result = nativeReadData(handle.getMojoHandle(), null, numBytes, 279 flags.getFlags() | MOJO_READ_DATA_FLAG_DISCARD); 280 if (result < 0) { 281 throw new MojoException(result); 282 } 283 return result; 284 } 285 286 /** 287 * @see ConsumerHandle#readData(ByteBuffer, DataPipe.ReadFlags) 288 */ readData(DataPipeConsumerHandleImpl handle, ByteBuffer elements, DataPipe.ReadFlags flags)289 int readData(DataPipeConsumerHandleImpl handle, ByteBuffer elements, 290 DataPipe.ReadFlags flags) { 291 int result = nativeReadData(handle.getMojoHandle(), elements, 292 elements == null ? 0 : elements.capacity(), 293 flags.getFlags()); 294 if (result < 0) { 295 throw new MojoException(result); 296 } 297 if (elements != null) { 298 elements.limit(result); 299 } 300 return result; 301 } 302 303 /** 304 * @see ConsumerHandle#beginReadData(int, DataPipe.ReadFlags) 305 */ beginReadData(DataPipeConsumerHandleImpl handle, int numBytes, DataPipe.ReadFlags flags)306 ByteBuffer beginReadData(DataPipeConsumerHandleImpl handle, 307 int numBytes, DataPipe.ReadFlags flags) { 308 NativeCodeAndBufferResult result = nativeBeginReadData( 309 handle.getMojoHandle(), 310 numBytes, 311 flags.getFlags()); 312 if (result.getMojoResult() != MojoResult.OK) { 313 throw new MojoException(result.getMojoResult()); 314 } 315 return result.getBuffer().asReadOnlyBuffer(); 316 } 317 318 /** 319 * @see ConsumerHandle#endReadData(int) 320 */ endReadData(DataPipeConsumerHandleImpl handle, int numBytesRead)321 void endReadData(DataPipeConsumerHandleImpl handle, 322 int numBytesRead) { 323 int result = nativeEndReadData(handle.getMojoHandle(), numBytesRead); 324 if (result != MojoResult.OK) { 325 throw new MojoException(result); 326 } 327 } 328 329 /** 330 * @see ProducerHandle#writeData(ByteBuffer, DataPipe.WriteFlags) 331 */ writeData(DataPipeProducerHandleImpl handle, ByteBuffer elements, DataPipe.WriteFlags flags)332 int writeData(DataPipeProducerHandleImpl handle, ByteBuffer elements, 333 DataPipe.WriteFlags flags) { 334 return nativeWriteData(handle.getMojoHandle(), elements, elements.limit(), 335 flags.getFlags()); 336 } 337 338 /** 339 * @see ProducerHandle#beginWriteData(int, DataPipe.WriteFlags) 340 */ beginWriteData(DataPipeProducerHandleImpl handle, int numBytes, DataPipe.WriteFlags flags)341 ByteBuffer beginWriteData(DataPipeProducerHandleImpl handle, 342 int numBytes, DataPipe.WriteFlags flags) { 343 NativeCodeAndBufferResult result = nativeBeginWriteData( 344 handle.getMojoHandle(), 345 numBytes, 346 flags.getFlags()); 347 if (result.getMojoResult() != MojoResult.OK) { 348 throw new MojoException(result.getMojoResult()); 349 } 350 return result.getBuffer(); 351 } 352 353 /** 354 * @see ProducerHandle#endWriteData(int) 355 */ endWriteData(DataPipeProducerHandleImpl handle, int numBytesWritten)356 void endWriteData(DataPipeProducerHandleImpl handle, 357 int numBytesWritten) { 358 int result = nativeEndWriteData(handle.getMojoHandle(), numBytesWritten); 359 if (result != MojoResult.OK) { 360 throw new MojoException(result); 361 } 362 } 363 364 /** 365 * @see SharedBufferHandle#duplicate(DuplicateOptions) 366 */ duplicate(SharedBufferHandleImpl handle, DuplicateOptions options)367 SharedBufferHandle duplicate(SharedBufferHandleImpl handle, 368 DuplicateOptions options) { 369 ByteBuffer optionsBuffer = null; 370 if (options != null) { 371 optionsBuffer = allocateDirectBuffer(8); 372 optionsBuffer.putInt(0, 8); 373 optionsBuffer.putInt(4, options.getFlags().getFlags()); 374 } 375 NativeCreationResult result = nativeDuplicate(handle.getMojoHandle(), 376 optionsBuffer); 377 if (result.getMojoResult() != MojoResult.OK) { 378 throw new MojoException(result.getMojoResult()); 379 } 380 assert result.getMojoHandle2() == 0; 381 return new SharedBufferHandleImpl(this, result.getMojoHandle1()); 382 } 383 384 /** 385 * @see SharedBufferHandle#map(long, long, MapFlags) 386 */ map(SharedBufferHandleImpl handle, long offset, long numBytes, MapFlags flags)387 ByteBuffer map(SharedBufferHandleImpl handle, long offset, long numBytes, 388 MapFlags flags) { 389 NativeCodeAndBufferResult result = nativeMap(handle.getMojoHandle(), offset, numBytes, 390 flags.getFlags()); 391 if (result.getMojoResult() != MojoResult.OK) { 392 throw new MojoException(result.getMojoResult()); 393 } 394 return result.getBuffer(); 395 } 396 397 /** 398 * @see SharedBufferHandle#unmap(ByteBuffer) 399 */ unmap(ByteBuffer buffer)400 void unmap(ByteBuffer buffer) { 401 int result = nativeUnmap(buffer); 402 if (result != MojoResult.OK) { 403 throw new MojoException(result); 404 } 405 } 406 407 /** 408 * @return the mojo handle associated to the given handle, considering invalid handles. 409 */ getMojoHandle(Handle handle)410 private int getMojoHandle(Handle handle) { 411 if (handle.isValid()) { 412 return ((HandleBase) handle).getMojoHandle(); 413 } 414 return 0; 415 } 416 isUnrecoverableError(int code)417 private static boolean isUnrecoverableError(int code) { 418 switch (code) { 419 case MojoResult.OK: 420 case MojoResult.DEADLINE_EXCEEDED: 421 case MojoResult.CANCELLED: 422 case MojoResult.FAILED_PRECONDITION: 423 return false; 424 default: 425 return true; 426 } 427 } 428 filterMojoResult(int code)429 private static int filterMojoResult(int code) { 430 if (code >= 0) { 431 return MojoResult.OK; 432 } 433 return code; 434 } 435 filterMojoResultForWait(int code)436 private static int filterMojoResultForWait(int code) { 437 int finalCode = filterMojoResult(code); 438 if (isUnrecoverableError(finalCode)) { 439 throw new MojoException(finalCode); 440 } 441 return finalCode; 442 } 443 allocateDirectBuffer(int capacity)444 private static ByteBuffer allocateDirectBuffer(int capacity) { 445 ByteBuffer buffer = ByteBuffer.allocateDirect(capacity); 446 buffer.order(ByteOrder.nativeOrder()); 447 return buffer; 448 } 449 450 private static class NativeCodeAndBufferResult { 451 private int mMojoResult; 452 private ByteBuffer mBuffer; 453 454 /** 455 * @return the mojoResult 456 */ getMojoResult()457 public int getMojoResult() { 458 return mMojoResult; 459 } 460 461 /** 462 * @param mojoResult the mojoResult to set 463 */ setMojoResult(int mojoResult)464 public void setMojoResult(int mojoResult) { 465 mMojoResult = mojoResult; 466 } 467 468 /** 469 * @return the buffer 470 */ getBuffer()471 public ByteBuffer getBuffer() { 472 return mBuffer; 473 } 474 475 /** 476 * @param buffer the buffer to set 477 */ setBuffer(ByteBuffer buffer)478 public void setBuffer(ByteBuffer buffer) { 479 mBuffer = buffer; 480 } 481 482 } 483 484 /** 485 * Implementation of {@link org.chromium.mojo.system.AsyncWaiter.Cancellable}. 486 */ 487 private class AsyncWaiterCancellableImpl implements AsyncWaiter.Cancellable { 488 489 private final long mId; 490 private final long mDataPtr; 491 private boolean mActive = true; 492 AsyncWaiterCancellableImpl(long id, long dataPtr)493 private AsyncWaiterCancellableImpl(long id, long dataPtr) { 494 this.mId = id; 495 this.mDataPtr = dataPtr; 496 } 497 498 /** 499 * @see org.chromium.mojo.system.AsyncWaiter.Cancellable#cancel() 500 */ 501 @Override cancel()502 public void cancel() { 503 if (mActive) { 504 mActive = false; 505 nativeCancelAsyncWait(mId, mDataPtr); 506 } 507 } 508 isActive()509 private boolean isActive() { 510 return mActive; 511 } 512 deactivate()513 private void deactivate() { 514 mActive = false; 515 } 516 } 517 518 @CalledByNative newAsyncWaiterCancellableImpl(long id, long dataPtr)519 private AsyncWaiterCancellableImpl newAsyncWaiterCancellableImpl(long id, long dataPtr) { 520 return new AsyncWaiterCancellableImpl(id, dataPtr); 521 } 522 523 @CalledByNative onAsyncWaitResult(int mojoResult, AsyncWaiter.Callback callback, AsyncWaiterCancellableImpl cancellable)524 private void onAsyncWaitResult(int mojoResult, 525 AsyncWaiter.Callback callback, 526 AsyncWaiterCancellableImpl cancellable) { 527 if (!cancellable.isActive()) { 528 // If cancellable is not active, the user cancelled the wait. 529 return; 530 } 531 cancellable.deactivate(); 532 int finalCode = filterMojoResult(mojoResult); 533 if (isUnrecoverableError(finalCode)) { 534 callback.onError(new MojoException(finalCode)); 535 return; 536 } 537 callback.onResult(finalCode); 538 } 539 540 @CalledByNative newNativeCodeAndBufferResult(int mojoResult, ByteBuffer buffer)541 private static NativeCodeAndBufferResult newNativeCodeAndBufferResult(int mojoResult, 542 ByteBuffer buffer) { 543 NativeCodeAndBufferResult result = new NativeCodeAndBufferResult(); 544 result.setMojoResult(mojoResult); 545 result.setBuffer(buffer); 546 return result; 547 } 548 549 @CalledByNative newReadMessageResult(int mojoResult, int messageSize, int handlesCount)550 private static MessagePipeHandle.ReadMessageResult newReadMessageResult(int mojoResult, 551 int messageSize, 552 int handlesCount) { 553 MessagePipeHandle.ReadMessageResult result = new MessagePipeHandle.ReadMessageResult(); 554 if (mojoResult >= 0) { 555 result.setMojoResult(MojoResult.OK); 556 } else { 557 result.setMojoResult(mojoResult); 558 } 559 result.setMessageSize(messageSize); 560 result.setHandlesCount(handlesCount); 561 return result; 562 } 563 564 private static class NativeCreationResult { 565 private int mMojoResult; 566 private int mMojoHandle1; 567 private int mMojoHandle2; 568 569 /** 570 * @return the mojoResult 571 */ getMojoResult()572 public int getMojoResult() { 573 return mMojoResult; 574 } 575 576 /** 577 * @param mojoResult the mojoResult to set 578 */ setMojoResult(int mojoResult)579 public void setMojoResult(int mojoResult) { 580 mMojoResult = mojoResult; 581 } 582 583 /** 584 * @return the mojoHandle1 585 */ getMojoHandle1()586 public int getMojoHandle1() { 587 return mMojoHandle1; 588 } 589 590 /** 591 * @param mojoHandle1 the mojoHandle1 to set 592 */ setMojoHandle1(int mojoHandle1)593 public void setMojoHandle1(int mojoHandle1) { 594 mMojoHandle1 = mojoHandle1; 595 } 596 597 /** 598 * @return the mojoHandle2 599 */ getMojoHandle2()600 public int getMojoHandle2() { 601 return mMojoHandle2; 602 } 603 604 /** 605 * @param mojoHandle2 the mojoHandle2 to set 606 */ setMojoHandle2(int mojoHandle2)607 public void setMojoHandle2(int mojoHandle2) { 608 mMojoHandle2 = mojoHandle2; 609 } 610 } 611 612 @CalledByNative newNativeCreationResult(int mojoResult, int mojoHandle1, int mojoHandle2)613 private static NativeCreationResult newNativeCreationResult(int mojoResult, 614 int mojoHandle1, int mojoHandle2) { 615 NativeCreationResult result = new NativeCreationResult(); 616 result.setMojoResult(mojoResult); 617 result.setMojoHandle1(mojoHandle1); 618 result.setMojoHandle2(mojoHandle2); 619 return result; 620 } 621 nativeGetTimeTicksNow()622 private native long nativeGetTimeTicksNow(); 623 nativeWaitMany(ByteBuffer buffer, long deadline)624 private native int nativeWaitMany(ByteBuffer buffer, long deadline); 625 nativeCreateMessagePipe(ByteBuffer optionsBuffer)626 private native NativeCreationResult nativeCreateMessagePipe(ByteBuffer optionsBuffer); 627 nativeCreateDataPipe(ByteBuffer optionsBuffer)628 private native NativeCreationResult nativeCreateDataPipe(ByteBuffer optionsBuffer); 629 nativeCreateSharedBuffer(ByteBuffer optionsBuffer, long numBytes)630 private native NativeCreationResult nativeCreateSharedBuffer(ByteBuffer optionsBuffer, 631 long numBytes); 632 nativeClose(int mojoHandle)633 private native int nativeClose(int mojoHandle); 634 nativeWait(int mojoHandle, int signals, long deadline)635 private native int nativeWait(int mojoHandle, int signals, long deadline); 636 nativeWriteMessage(int mojoHandle, ByteBuffer bytes, int numBytes, ByteBuffer handlesBuffer, int flags)637 private native int nativeWriteMessage(int mojoHandle, ByteBuffer bytes, int numBytes, 638 ByteBuffer handlesBuffer, int flags); 639 nativeReadMessage(int mojoHandle, ByteBuffer bytes, ByteBuffer handlesBuffer, int flags)640 private native MessagePipeHandle.ReadMessageResult nativeReadMessage(int mojoHandle, 641 ByteBuffer bytes, 642 ByteBuffer handlesBuffer, 643 int flags); 644 nativeReadData(int mojoHandle, ByteBuffer elements, int elementsSize, int flags)645 private native int nativeReadData(int mojoHandle, ByteBuffer elements, int elementsSize, 646 int flags); 647 nativeBeginReadData(int mojoHandle, int numBytes, int flags)648 private native NativeCodeAndBufferResult nativeBeginReadData(int mojoHandle, int numBytes, 649 int flags); 650 nativeEndReadData(int mojoHandle, int numBytesRead)651 private native int nativeEndReadData(int mojoHandle, int numBytesRead); 652 nativeWriteData(int mojoHandle, ByteBuffer elements, int limit, int flags)653 private native int nativeWriteData(int mojoHandle, ByteBuffer elements, int limit, int flags); 654 nativeBeginWriteData(int mojoHandle, int numBytes, int flags)655 private native NativeCodeAndBufferResult nativeBeginWriteData(int mojoHandle, int numBytes, 656 int flags); 657 nativeEndWriteData(int mojoHandle, int numBytesWritten)658 private native int nativeEndWriteData(int mojoHandle, int numBytesWritten); 659 nativeDuplicate(int mojoHandle, ByteBuffer optionsBuffer)660 private native NativeCreationResult nativeDuplicate(int mojoHandle, ByteBuffer optionsBuffer); 661 nativeMap(int mojoHandle, long offset, long numBytes, int flags)662 private native NativeCodeAndBufferResult nativeMap(int mojoHandle, long offset, long numBytes, 663 int flags); 664 nativeUnmap(ByteBuffer buffer)665 private native int nativeUnmap(ByteBuffer buffer); 666 nativeAsyncWait(int mojoHandle, int signals, long deadline, AsyncWaiter.Callback callback)667 private native AsyncWaiterCancellableImpl nativeAsyncWait(int mojoHandle, int signals, 668 long deadline, AsyncWaiter.Callback callback); 669 nativeCancelAsyncWait(long mId, long dataPtr)670 private native void nativeCancelAsyncWait(long mId, long dataPtr); 671 } 672