This source file includes following definitions.
- DispatcherTryStartTransport
- TryStartTransport
- GetMaximumSerializedSize
- SerializeAndClose
- Deserialize
- Close
- WriteMessage
- ReadMessage
- WriteData
- BeginWriteData
- EndWriteData
- ReadData
- BeginReadData
- EndReadData
- DuplicateBufferHandle
- MapBuffer
- AddWaiter
- RemoveWaiter
- CancelAllWaitersNoLock
- CloseImplNoLock
- WriteMessageImplNoLock
- ReadMessageImplNoLock
- WriteDataImplNoLock
- BeginWriteDataImplNoLock
- EndWriteDataImplNoLock
- ReadDataImplNoLock
- BeginReadDataImplNoLock
- EndReadDataImplNoLock
- DuplicateBufferHandleImplNoLock
- MapBufferImplNoLock
- AddWaiterImplNoLock
- RemoveWaiterImplNoLock
- GetMaximumSerializedSizeImplNoLock
- SerializeAndCloseImplNoLock
- IsBusyNoLock
- CloseNoLock
- CreateEquivalentDispatcherAndCloseNoLock
- GetMaximumSerializedSize
- SerializeAndClose
- End
#include "mojo/system/dispatcher.h"
#include "base/logging.h"
#include "mojo/system/constants.h"
#include "mojo/system/message_pipe_dispatcher.h"
namespace mojo {
namespace system {
namespace test {
DispatcherTransport DispatcherTryStartTransport(
Dispatcher* dispatcher) {
return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher);
}
}
DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport(
Dispatcher* dispatcher) {
DCHECK(dispatcher);
if (!dispatcher->lock_.Try())
return DispatcherTransport();
DCHECK(!dispatcher->is_closed_);
return DispatcherTransport(dispatcher);
}
size_t Dispatcher::MessageInTransitAccess::GetMaximumSerializedSize(
const Dispatcher* dispatcher,
const Channel* channel) {
DCHECK(dispatcher);
return dispatcher->GetMaximumSerializedSize(channel);
}
bool Dispatcher::MessageInTransitAccess::SerializeAndClose(
Dispatcher* dispatcher,
Channel* channel,
void* destination,
size_t* actual_size) {
DCHECK(dispatcher);
return dispatcher->SerializeAndClose(channel, destination, actual_size);
}
scoped_refptr<Dispatcher> Dispatcher::MessageInTransitAccess::Deserialize(
Channel* channel,
int32_t type,
const void* source,
size_t size) {
switch (static_cast<int32_t>(type)) {
case kTypeUnknown:
DVLOG(2) << "Deserializing invalid handle";
return scoped_refptr<Dispatcher>();
case kTypeMessagePipe:
return scoped_refptr<Dispatcher>(
MessagePipeDispatcher::Deserialize(channel, source, size));
case kTypeDataPipeProducer:
case kTypeDataPipeConsumer:
LOG(WARNING) << "Deserialization of dispatcher type " << type
<< " not supported";
return scoped_refptr<Dispatcher>();
}
LOG(WARNING) << "Unknown dispatcher type " << type;
return scoped_refptr<Dispatcher>();
}
MojoResult Dispatcher::Close() {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
CloseNoLock();
return MOJO_RESULT_OK;
}
MojoResult Dispatcher::WriteMessage(
const void* bytes,
uint32_t num_bytes,
std::vector<DispatcherTransport>* transports,
MojoWriteMessageFlags flags) {
DCHECK(!transports || (transports->size() > 0 &&
transports->size() < kMaxMessageNumHandles));
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return WriteMessageImplNoLock(bytes, num_bytes, transports, flags);
}
MojoResult Dispatcher::ReadMessage(
void* bytes,
uint32_t* num_bytes,
std::vector<scoped_refptr<Dispatcher> >* dispatchers,
uint32_t* num_dispatchers,
MojoReadMessageFlags flags) {
DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
(dispatchers && dispatchers->empty()));
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers,
flags);
}
MojoResult Dispatcher::WriteData(const void* elements,
uint32_t* num_bytes,
MojoWriteDataFlags flags) {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return WriteDataImplNoLock(elements, num_bytes, flags);
}
MojoResult Dispatcher::BeginWriteData(void** buffer,
uint32_t* buffer_num_bytes,
MojoWriteDataFlags flags) {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags);
}
MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return EndWriteDataImplNoLock(num_bytes_written);
}
MojoResult Dispatcher::ReadData(void* elements,
uint32_t* num_bytes,
MojoReadDataFlags flags) {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return ReadDataImplNoLock(elements, num_bytes, flags);
}
MojoResult Dispatcher::BeginReadData(const void** buffer,
uint32_t* buffer_num_bytes,
MojoReadDataFlags flags) {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags);
}
MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return EndReadDataImplNoLock(num_bytes_read);
}
MojoResult Dispatcher::DuplicateBufferHandle(
const MojoDuplicateBufferHandleOptions* options,
scoped_refptr<Dispatcher>* new_dispatcher) {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return DuplicateBufferHandleImplNoLock(options, new_dispatcher);
}
MojoResult Dispatcher::MapBuffer(
uint64_t offset,
uint64_t num_bytes,
MojoMapBufferFlags flags,
scoped_ptr<RawSharedBufferMapping>* mapping) {
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return MapBufferImplNoLock(offset, num_bytes, flags, mapping);
}
MojoResult Dispatcher::AddWaiter(Waiter* waiter,
MojoWaitFlags flags,
MojoResult wake_result) {
DCHECK_GE(wake_result, 0);
base::AutoLock locker(lock_);
if (is_closed_)
return MOJO_RESULT_INVALID_ARGUMENT;
return AddWaiterImplNoLock(waiter, flags, wake_result);
}
void Dispatcher::RemoveWaiter(Waiter* waiter) {
base::AutoLock locker(lock_);
if (is_closed_)
return;
RemoveWaiterImplNoLock(waiter);
}
Dispatcher::Dispatcher()
: is_closed_(false) {
}
Dispatcher::~Dispatcher() {
DCHECK(is_closed_);
}
void Dispatcher::CancelAllWaitersNoLock() {
lock_.AssertAcquired();
DCHECK(is_closed_);
}
void Dispatcher::CloseImplNoLock() {
lock_.AssertAcquired();
DCHECK(is_closed_);
}
MojoResult Dispatcher::WriteMessageImplNoLock(
const void* ,
uint32_t ,
std::vector<DispatcherTransport>* ,
MojoWriteMessageFlags ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::ReadMessageImplNoLock(
void* ,
uint32_t* ,
std::vector<scoped_refptr<Dispatcher> >* ,
uint32_t* ,
MojoReadMessageFlags ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::WriteDataImplNoLock(const void* ,
uint32_t* ,
MojoWriteDataFlags ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::BeginWriteDataImplNoLock(void** ,
uint32_t* ,
MojoWriteDataFlags ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::ReadDataImplNoLock(void* ,
uint32_t* ,
MojoReadDataFlags ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::BeginReadDataImplNoLock(const void** ,
uint32_t* ,
MojoReadDataFlags ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::DuplicateBufferHandleImplNoLock(
const MojoDuplicateBufferHandleOptions* ,
scoped_refptr<Dispatcher>* ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::MapBufferImplNoLock(
uint64_t ,
uint64_t ,
MojoMapBufferFlags ,
scoped_ptr<RawSharedBufferMapping>* ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* ,
MojoWaitFlags ,
MojoResult ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return MOJO_RESULT_FAILED_PRECONDITION;
}
void Dispatcher::RemoveWaiterImplNoLock(Waiter* ) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
}
size_t Dispatcher::GetMaximumSerializedSizeImplNoLock(
const Channel* ) const {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return 0;
}
bool Dispatcher::SerializeAndCloseImplNoLock(Channel* ,
void* ,
size_t* ) {
lock_.AssertAcquired();
DCHECK(is_closed_);
CloseImplNoLock();
return 0;
}
bool Dispatcher::IsBusyNoLock() const {
lock_.AssertAcquired();
DCHECK(!is_closed_);
return false;
}
void Dispatcher::CloseNoLock() {
lock_.AssertAcquired();
DCHECK(!is_closed_);
is_closed_ = true;
CancelAllWaitersNoLock();
CloseImplNoLock();
}
scoped_refptr<Dispatcher>
Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
lock_.AssertAcquired();
DCHECK(!is_closed_);
is_closed_ = true;
CancelAllWaitersNoLock();
return CreateEquivalentDispatcherAndCloseImplNoLock();
}
size_t Dispatcher::GetMaximumSerializedSize(const Channel* channel) const {
DCHECK(channel);
DCHECK(HasOneRef());
base::AutoLock locker(lock_);
DCHECK(!is_closed_);
return GetMaximumSerializedSizeImplNoLock(channel);
}
bool Dispatcher::SerializeAndClose(Channel* channel,
void* destination,
size_t* actual_size) {
DCHECK(destination);
DCHECK(channel);
DCHECK(actual_size);
DCHECK(HasOneRef());
base::AutoLock locker(lock_);
DCHECK(!is_closed_);
#if DCHECK_IS_ON
size_t max_size = GetMaximumSerializedSizeImplNoLock(channel);
#else
size_t max_size = static_cast<size_t>(-1);
#endif
is_closed_ = true;
if (!SerializeAndCloseImplNoLock(channel, destination, actual_size))
return false;
DCHECK_LE(*actual_size, max_size);
return true;
}
void DispatcherTransport::End() {
DCHECK(dispatcher_);
dispatcher_->lock_.Release();
dispatcher_ = NULL;
}
}
}