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