Home | History | Annotate | Download | only in stream
      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 
     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 
     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 
     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.
     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 
     49 PP_CompletionCallback StreamFs::GetStartCompletion(Work* work) {
     50   return PP_MakeCompletionCallback(DispatchStart, work);
     51 }
     52 
     53 PP_CompletionCallback StreamFs::GetRunCompletion(Work* work) {
     54   return PP_MakeCompletionCallback(DispatchRun, work);
     55 }
     56 
     57 // Place enqueue onto the socket thread.
     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 
     75 StreamFs::StreamFs() : message_loop_(0) {
     76   pthread_cond_init(&message_cond_, NULL);
     77 }
     78 
     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 
     87 Error StreamFs::Access(const Path& path, int a_mode) {
     88   return EACCES;
     89 }
     90 
     91 Error StreamFs::Open(const Path& path, int o_flags, ScopedNode* out_node) {
     92   return EACCES;
     93 }
     94 
     95 Error StreamFs::Unlink(const Path& path) {
     96   return EACCES;
     97 }
     98 
     99 Error StreamFs::Mkdir(const Path& path, int permissions) {
    100   return EACCES;
    101 }
    102 
    103 Error StreamFs::Rmdir(const Path& path) {
    104   return EACCES;
    105 }
    106 
    107 Error StreamFs::Remove(const Path& path) {
    108   return EACCES;
    109 }
    110 
    111 Error StreamFs::Rename(const Path& path, const Path& newpath) {
    112   return EACCES;
    113 }
    114 
    115 }  // namespace nacl_io
    116