168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "nacl_io/ossocket.h"
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <errno.h>
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "nacl_io/mount_stream.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "nacl_io/pepper_interface.h"
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace nacl_io {
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DispatchStart(void* work_ptr, int32_t val) {
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MountStream::Work* work = static_cast<MountStream::Work*>(work_ptr);
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Delete if it fails to Start, Run will never get called.
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!work->Start(val))
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    delete work;
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DispatchRun(void* work_ptr, int32_t val) {
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MountStream::Work* work = static_cast<MountStream::Work*>(work_ptr);
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  work->Run(val);
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  delete work;
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void* MountStream::StreamThreadThunk(void* mount_ptr) {
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MountStream* mount = static_cast<MountStream*>(mount_ptr);
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  mount->StreamThread();
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return NULL;
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// All work is done via completions callbacks from posted work.
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MountStream::StreamThread() {
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    AUTO_LOCK(message_lock_)
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    message_loop_ =
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        ppapi_->GetMessageLoopInterface()->Create(ppapi()->GetInstance());
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ppapi_->GetMessageLoopInterface()->AttachToCurrentThread(message_loop_);
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    pthread_cond_broadcast(&message_cond_);
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Run loop until Quit is posted.
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ppapi_->GetMessageLoopInterface()->Run(message_loop_);
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)PP_CompletionCallback MountStream::GetStartCompletion(Work* work) {
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return PP_MakeCompletionCallback(DispatchStart, work);
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)PP_CompletionCallback MountStream::GetRunCompletion(Work* work) {
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return PP_MakeCompletionCallback(DispatchRun, work);
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Place enqueue onto the socket thread.
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MountStream::EnqueueWork(Work* work) {
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (message_loop_ == 0) {
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    AUTO_LOCK(message_lock_);
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (message_loop_ == 0) {
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      pthread_t thread;
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      pthread_create(&thread, NULL, StreamThreadThunk, this);
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    while (message_loop_ == 0)
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      pthread_cond_wait(&message_cond_, message_lock_.mutex());
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  PP_CompletionCallback cb = PP_MakeCompletionCallback(DispatchStart, work);
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ppapi_->GetMessageLoopInterface()->PostWork(message_loop_, cb, 0);
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MountStream::MountStream()
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : message_loop_(0) {
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  pthread_cond_init(&message_cond_, NULL);
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MountStream::~MountStream() {
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (message_loop_) {
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ppapi_->GetMessageLoopInterface()->PostQuit(message_loop_, PP_TRUE);
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ppapi_->ReleaseResource(message_loop_);
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  pthread_cond_destroy(&message_cond_);
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Error MountStream::Access(const Path& path, int a_mode) { return EACCES; }
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Error MountStream::Open(const Path& path,
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                        int o_flags,
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                        ScopedMountNode* out_node) { return EACCES; }
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Error MountStream::Unlink(const Path& path) { return EACCES; }
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Error MountStream::Mkdir(const Path& path, int permissions) { return EACCES; }
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Error MountStream::Rmdir(const Path& path) { return EACCES; }
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Error MountStream::Remove(const Path& path) { return EACCES; }
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)Error MountStream::Rename(const Path& path, const Path& newpath) {
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return EACCES;
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace nacl_io
107