| Index: native_client_sdk/src/libraries/nacl_io/mount_stream.cc
|
| diff --git a/native_client_sdk/src/libraries/nacl_io/mount_stream.cc b/native_client_sdk/src/libraries/nacl_io/mount_stream.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..71f218478982f3c2d9b7518231c9e32c690ce3ae
|
| --- /dev/null
|
| +++ b/native_client_sdk/src/libraries/nacl_io/mount_stream.cc
|
| @@ -0,0 +1,102 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "nacl_io/ossocket.h"
|
| +#ifdef PROVIDES_SOCKET_API
|
| +
|
| +#include <errno.h>
|
| +
|
| +#include "nacl_io/mount_node_socket.h"
|
| +#include "nacl_io/mount_stream.h"
|
| +
|
| +namespace nacl_io {
|
| +
|
| +
|
| +void DispatchStart(void* work_ptr, int32_t val) {
|
| + MountStream::Work* work = static_cast<MountStream::Work*>(work_ptr);
|
| +
|
| + // Delete if it fails to Start, Run will never get called.
|
| + if (!work->Start(val))
|
| + delete work;
|
| +}
|
| +
|
| +void DispatchRun(void* work_ptr, int32_t val) {
|
| + MountStream::Work* work = static_cast<MountStream::Work*>(work_ptr);
|
| +
|
| + work->Run(val);
|
| + delete work;
|
| +}
|
| +
|
| +void* MountStream::StreamThreadThunk(void* mount_ptr) {
|
| + MountStream* mount = static_cast<MountStream*>(mount_ptr);
|
| + mount->StreamThread();
|
| + return NULL;
|
| +}
|
| +
|
| +// All work is done via completions callbacks from posted work.
|
| +void MountStream::StreamThread() {
|
| + {
|
| + AUTO_LOCK(message_lock_)
|
| + message_loop_ =
|
| + ppapi_->GetMessageLoopInterface()->Create(ppapi()->GetInstance());
|
| + ppapi_->GetMessageLoopInterface()->AttachToCurrentThread(message_loop_);
|
| + pthread_cond_broadcast(&message_cond_);
|
| + }
|
| +
|
| + // Run loop until Quit is posted.
|
| + ppapi_->GetMessageLoopInterface()->Run(message_loop_);
|
| +}
|
| +
|
| +PP_CompletionCallback MountStream::GetStartCompletion(Work* work) {
|
| + return PP_MakeCompletionCallback(DispatchStart, work);
|
| +}
|
| +
|
| +PP_CompletionCallback MountStream::GetRunCompletion(Work* work) {
|
| + return PP_MakeCompletionCallback(DispatchRun, work);
|
| +}
|
| +
|
| +// Place enqueue onto the socket thread.
|
| +void MountStream::EnqueueWork(Work* work) {
|
| + if (message_loop_ == 0) {
|
| + AUTO_LOCK(message_lock_);
|
| +
|
| + if (message_loop_ == 0) {
|
| + pthread_t thread;
|
| + pthread_create(&thread, NULL, StreamThreadThunk, this);
|
| + }
|
| +
|
| + while (message_loop_ == 0)
|
| + pthread_cond_wait(&message_cond_, message_lock_.mutex());
|
| + }
|
| +
|
| + PP_CompletionCallback cb = PP_MakeCompletionCallback(DispatchStart, work);
|
| + ppapi_->GetMessageLoopInterface()->PostWork(message_loop_, cb, 0);
|
| +}
|
| +
|
| +
|
| +MountStream::MountStream()
|
| + : message_loop_(0) {
|
| + pthread_cond_init(&message_cond_, NULL);
|
| +}
|
| +
|
| +MountStream::~MountStream() {
|
| + if (message_loop_) {
|
| + ppapi_->GetMessageLoopInterface()->PostQuit(message_loop_, PP_TRUE);
|
| + ppapi_->ReleaseResource(message_loop_);
|
| + }
|
| + pthread_cond_destroy(&message_cond_);
|
| +}
|
| +
|
| +Error MountStream::Access(const Path& path, int a_mode) { return EACCES; }
|
| +Error MountStream::Open(const Path& path,
|
| + int o_flags,
|
| + ScopedMountNode* out_node) { return EACCES; }
|
| +
|
| +Error MountStream::Unlink(const Path& path) { return EACCES; }
|
| +Error MountStream::Mkdir(const Path& path, int permissions) { return EACCES; }
|
| +Error MountStream::Rmdir(const Path& path) { return EACCES; }
|
| +Error MountStream::Remove(const Path& path) { return EACCES; }
|
| +
|
| +} // namespace nacl_io
|
| +#endif // PROVIDES_SOCKET_API
|
|
|