• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 namespace nacl_io {
13 
DispatchStart(void * work_ptr,int32_t val)14 void 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 
DispatchRun(void * work_ptr,int32_t val)22 void 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 
StreamThreadThunk(void * fs_ptr)29 void* 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.
StreamThread()36 void 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 
GetStartCompletion(Work * work)49 PP_CompletionCallback StreamFs::GetStartCompletion(Work* work) {
50   return PP_MakeCompletionCallback(DispatchStart, work);
51 }
52 
GetRunCompletion(Work * work)53 PP_CompletionCallback StreamFs::GetRunCompletion(Work* work) {
54   return PP_MakeCompletionCallback(DispatchRun, work);
55 }
56 
57 // Place enqueue onto the socket thread.
EnqueueWork(Work * work)58 void 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 
StreamFs()75 StreamFs::StreamFs() : message_loop_(0) {
76   pthread_cond_init(&message_cond_, NULL);
77 }
78 
~StreamFs()79 StreamFs::~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 
Access(const Path & path,int a_mode)87 Error StreamFs::Access(const Path& path, int a_mode) {
88   return EACCES;
89 }
90 
Open(const Path & path,int o_flags,ScopedNode * out_node)91 Error StreamFs::Open(const Path& path, int o_flags, ScopedNode* out_node) {
92   return EACCES;
93 }
94 
Unlink(const Path & path)95 Error StreamFs::Unlink(const Path& path) {
96   return EACCES;
97 }
98 
Mkdir(const Path & path,int permissions)99 Error StreamFs::Mkdir(const Path& path, int permissions) {
100   return EACCES;
101 }
102 
Rmdir(const Path & path)103 Error StreamFs::Rmdir(const Path& path) {
104   return EACCES;
105 }
106 
Remove(const Path & path)107 Error StreamFs::Remove(const Path& path) {
108   return EACCES;
109 }
110 
Rename(const Path & path,const Path & newpath)111 Error StreamFs::Rename(const Path& path, const Path& newpath) {
112   return EACCES;
113 }
114 
115 }  // namespace nacl_io
116