Chromium Code Reviews| 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..d742dc3f00e07f9bf352c33b2466e106b3c2639d |
| --- /dev/null |
| +++ b/native_client_sdk/src/libraries/nacl_io/mount_stream.cc |
| @@ -0,0 +1,90 @@ |
| +// 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) { |
| + MountStreamWork* work = static_cast<MountStreamWork*>(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) { |
| + MountStreamWork* work = static_cast<MountStreamWork*>(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_); |
| + } |
| + |
| + while(1) |
|
binji
2013/09/15 22:18:58
no way to exit the loop?
noelallen1
2013/09/17 21:21:54
Done.
|
| + ppapi_->GetMessageLoopInterface()->Run(message_loop_); |
| +} |
| + |
| +PP_CompletionCallback MountStream::GetStartCompletion(MountStreamWork* work) { |
| + return PP_MakeCompletionCallback(DispatchStart, work); |
| +} |
| + |
| +PP_CompletionCallback MountStream::GetRunCompletion(MountStreamWork* work) { |
| + return PP_MakeCompletionCallback(DispatchRun, work); |
| +} |
| + |
| +// Place enqueue onto the socket thread. |
| +void MountStream::EnqueueWork(MountStreamWork* work) { |
| + if (message_loop_ == 0) { |
|
binji
2013/09/15 22:18:58
looks racy. What happens if two threads enqueue wo
noelallen1
2013/09/17 21:21:54
Done.
binji
2013/09/19 00:48:54
Probably should use pthread_once_t instead of doub
noelallen1
2013/09/19 21:29:27
The once init routine doesn't take a parameter, so
|
| + AUTO_LOCK(message_lock_); |
| + 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) { |
| +} |
| + |
| +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 |