1// RequestThread.cpp 2 3#include <new> 4 5#include <TLS.h> 6 7#include "RequestThread.h" 8#include "ServerDefs.h" 9#include "UserlandRequestHandler.h" 10 11static const int32 sTLSVariable = tls_allocate(); 12 13// constructor 14RequestThreadContext::RequestThreadContext(UserVolume* volume) 15 : fPreviousContext(NULL), 16 fThread(NULL), 17 fVolume(volume) 18{ 19 fThread = RequestThread::GetCurrentThread(); 20 if (fThread) { 21 fPreviousContext = fThread->GetContext(); 22 fThread->SetContext(this); 23 } 24} 25 26// destructor 27RequestThreadContext::~RequestThreadContext() 28{ 29 if (fThread) 30 fThread->SetContext(fPreviousContext); 31} 32 33// GetThread 34RequestThread* 35RequestThreadContext::GetThread() const 36{ 37 return fThread; 38} 39 40// GetVolume 41UserlandFS::UserVolume* 42RequestThreadContext::GetVolume() const 43{ 44 return fVolume; 45} 46 47 48// RequestThread 49 50// constructor 51RequestThread::RequestThread() 52 : fThread(-1), 53 fFileSystem(NULL), 54 fPort(NULL), 55 fContext(NULL), 56 fTerminating(false) 57{ 58} 59 60// destructor 61RequestThread::~RequestThread() 62{ 63 PrepareTermination(); 64 Terminate(); 65 delete fPort; 66} 67 68// Init 69status_t 70RequestThread::Init(UserFileSystem* fileSystem) 71{ 72 if (!fileSystem) 73 return B_BAD_VALUE; 74 // create the port 75 fPort = new(nothrow) RequestPort(kRequestPortSize); 76 if (!fPort) 77 return B_NO_MEMORY; 78 status_t error = fPort->InitCheck(); 79 if (error != B_OK) 80 return error; 81 // spawn the thread 82 fThread = spawn_thread(_ThreadEntry, "request thread", B_NORMAL_PRIORITY, 83 this); 84 if (fThread < 0) 85 return fThread; 86 fFileSystem = fileSystem; 87 return B_OK; 88} 89 90// Run 91void 92RequestThread::Run() 93{ 94 resume_thread(fThread); 95} 96 97// PrepareTermination 98void 99RequestThread::PrepareTermination() 100{ 101 if (fTerminating) 102 return; 103 fTerminating = true; 104 if (fPort) 105 fPort->Close(); 106} 107 108// Terminate 109void 110RequestThread::Terminate() 111{ 112 if (fThread >= 0) { 113 int32 result; 114 wait_for_thread(fThread, &result); 115 fThread = -1; 116 } 117} 118 119// GetPortInfo 120const Port::Info* 121RequestThread::GetPortInfo() const 122{ 123 return (fPort ? fPort->GetPortInfo() : NULL); 124} 125 126// GetFileSystem 127UserlandFS::UserFileSystem* 128RequestThread::GetFileSystem() const 129{ 130 return fFileSystem; 131} 132 133// GetPort 134RequestPort* 135RequestThread::GetPort() const 136{ 137 return fPort; 138} 139 140// GetContext 141RequestThreadContext* 142RequestThread::GetContext() const 143{ 144 return fContext; 145} 146 147// GetCurrentThread 148RequestThread* 149RequestThread::GetCurrentThread() 150{ 151 return (RequestThread*)tls_get(sTLSVariable); 152} 153 154// SetContext 155void 156RequestThread::SetContext(RequestThreadContext* context) 157{ 158 fContext = context; 159} 160 161// _ThreadEntry 162int32 163RequestThread::_ThreadEntry(void* data) 164{ 165 return ((RequestThread*)data)->_ThreadLoop(); 166} 167 168// _ThreadLoop 169int32 170RequestThread::_ThreadLoop() 171{ 172 tls_set(sTLSVariable, this); 173 if (!fTerminating) { 174 UserlandRequestHandler handler(fFileSystem, false); 175 return fPort->HandleRequests(&handler); 176 } 177 return B_OK; 178} 179 180