1// Copyright 2013 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#include "nacl_io/stream/stream_fs.h" 6 7#include <errno.h> 8 9#include "nacl_io/ossocket.h" 10#include "nacl_io/pepper_interface.h" 11 12namespace nacl_io { 13 14void DispatchStart(void* work_ptr, int32_t val) { 15 StreamFs::Work* work = static_cast<StreamFs::Work*>(work_ptr); 16 17 // Delete if it fails to Start, Run will never get called. 18 if (!work->Start(val)) 19 delete work; 20} 21 22void DispatchRun(void* work_ptr, int32_t val) { 23 StreamFs::Work* work = static_cast<StreamFs::Work*>(work_ptr); 24 25 work->Run(val); 26 delete work; 27} 28 29void* StreamFs::StreamThreadThunk(void* fs_ptr) { 30 StreamFs* filesystem = static_cast<StreamFs*>(fs_ptr); 31 filesystem->StreamThread(); 32 return NULL; 33} 34 35// All work is done via completions callbacks from posted work. 36void StreamFs::StreamThread() { 37 { 38 AUTO_LOCK(message_lock_) 39 message_loop_ = 40 ppapi_->GetMessageLoopInterface()->Create(ppapi()->GetInstance()); 41 ppapi_->GetMessageLoopInterface()->AttachToCurrentThread(message_loop_); 42 pthread_cond_broadcast(&message_cond_); 43 } 44 45 // Run loop until Quit is posted. 46 ppapi_->GetMessageLoopInterface()->Run(message_loop_); 47} 48 49PP_CompletionCallback StreamFs::GetStartCompletion(Work* work) { 50 return PP_MakeCompletionCallback(DispatchStart, work); 51} 52 53PP_CompletionCallback StreamFs::GetRunCompletion(Work* work) { 54 return PP_MakeCompletionCallback(DispatchRun, work); 55} 56 57// Place enqueue onto the socket thread. 58void StreamFs::EnqueueWork(Work* work) { 59 if (message_loop_ == 0) { 60 AUTO_LOCK(message_lock_); 61 62 if (message_loop_ == 0) { 63 pthread_t thread; 64 pthread_create(&thread, NULL, StreamThreadThunk, this); 65 } 66 67 while (message_loop_ == 0) 68 pthread_cond_wait(&message_cond_, message_lock_.mutex()); 69 } 70 71 PP_CompletionCallback cb = PP_MakeCompletionCallback(DispatchStart, work); 72 ppapi_->GetMessageLoopInterface()->PostWork(message_loop_, cb, 0); 73} 74 75StreamFs::StreamFs() : message_loop_(0) { 76 pthread_cond_init(&message_cond_, NULL); 77} 78 79StreamFs::~StreamFs() { 80 if (message_loop_) { 81 ppapi_->GetMessageLoopInterface()->PostQuit(message_loop_, PP_TRUE); 82 ppapi_->ReleaseResource(message_loop_); 83 } 84 pthread_cond_destroy(&message_cond_); 85} 86 87Error StreamFs::OpenWithMode(const Path& path, int o_flags, mode_t mode, 88 ScopedNode* out_node) { 89 return EACCES; 90} 91 92Error StreamFs::Unlink(const Path& path) { 93 return EACCES; 94} 95 96Error StreamFs::Mkdir(const Path& path, int permissions) { 97 return EACCES; 98} 99 100Error StreamFs::Rmdir(const Path& path) { 101 return EACCES; 102} 103 104Error StreamFs::Remove(const Path& path) { 105 return EACCES; 106} 107 108Error StreamFs::Rename(const Path& path, const Path& newpath) { 109 return EACCES; 110} 111 112} // namespace nacl_io 113