| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <assert.h> | 7 #include <assert.h> |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 #include <exception> | 9 #include <exception> |
| 10 #include <stdexcept> | 10 #include <stdexcept> |
| 11 | 11 |
| 12 #include "native_client/src/shared/platform/nacl_log.h" |
| 12 #include "native_client/src/trusted/port/mutex.h" | 13 #include "native_client/src/trusted/port/mutex.h" |
| 13 #include "native_client/src/trusted/port/thread.h" | 14 #include "native_client/src/trusted/port/thread.h" |
| 14 | 15 |
| 15 /* | 16 /* |
| 16 * Define the OS specific portions of IThread interface. | 17 * Define the OS specific portions of IThread interface. |
| 17 */ | 18 */ |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 const int kDBG_PRINTEXCEPTION_C = 0x40010006; | 21 const int kDBG_PRINTEXCEPTION_C = 0x40010006; |
| 21 } | 22 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 case 15:return sizeof ctx->SegGs; | 203 case 15:return sizeof ctx->SegGs; |
| 203 } | 204 } |
| 204 | 205 |
| 205 throw std::out_of_range("Register index out of range."); | 206 throw std::out_of_range("Register index out of range."); |
| 206 } | 207 } |
| 207 #endif | 208 #endif |
| 208 | 209 |
| 209 | 210 |
| 210 class Thread : public IThread { | 211 class Thread : public IThread { |
| 211 public: | 212 public: |
| 212 explicit Thread(uint32_t id) : ref_(1), id_(id), | 213 Thread(uint32_t id, struct NaClAppThread *natp) |
| 213 handle_(NULL), state_(RUNNING) { | 214 : ref_(1), id_(id), handle_(NULL), natp_(natp), state_(RUNNING) { |
| 214 handle_ = OpenThread(THREAD_ALL_ACCESS, false, id); | 215 handle_ = OpenThread(THREAD_ALL_ACCESS, false, id); |
| 215 memset(&context_, 0, sizeof(context_)); | 216 memset(&context_, 0, sizeof(context_)); |
| 216 context_.ContextFlags = CONTEXT_ALL; | 217 context_.ContextFlags = CONTEXT_ALL; |
| 217 if (NULL == handle_) state_ = DEAD; | 218 if (NULL == handle_) state_ = DEAD; |
| 218 } | 219 } |
| 219 | 220 |
| 220 ~Thread() { | 221 ~Thread() { |
| 221 if (NULL == handle_) return; | 222 if (NULL == handle_) return; |
| 222 | 223 |
| 223 // This should always succeed, so ignore the return. | 224 // This should always succeed, so ignore the return. |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 | 355 |
| 355 thread->state_ = old_state; | 356 thread->state_ = old_state; |
| 356 Release(thread); | 357 Release(thread); |
| 357 return EXCEPTION_CONTINUE_EXECUTION; | 358 return EXCEPTION_CONTINUE_EXECUTION; |
| 358 } | 359 } |
| 359 | 360 |
| 360 | 361 |
| 361 private: | 362 private: |
| 362 uint32_t ref_; | 363 uint32_t ref_; |
| 363 uint32_t id_; | 364 uint32_t id_; |
| 365 struct NaClAppThread *natp_; |
| 364 State state_; | 366 State state_; |
| 365 HANDLE handle_; | 367 HANDLE handle_; |
| 366 CONTEXT context_; | 368 CONTEXT context_; |
| 367 | 369 |
| 368 friend class IThread; | 370 friend class IThread; |
| 369 }; | 371 }; |
| 370 | 372 |
| 371 IThread* IThread::Acquire(uint32_t id, bool create) { | 373 IThread* IThread::Create(uint32_t id, struct NaClAppThread* natp) { |
| 372 MutexLock lock(ThreadGetLock()); | 374 MutexLock lock(ThreadGetLock()); |
| 373 Thread* thread; | 375 Thread* thread; |
| 374 ThreadMap_t &map = *ThreadGetMap(); | 376 ThreadMap_t &map = *ThreadGetMap(); |
| 375 | 377 |
| 376 // Check if we have that thread | |
| 377 if (map.count(id)) { | 378 if (map.count(id)) { |
| 378 thread = static_cast<Thread*>(map[id]); | 379 NaClLog(LOG_FATAL, "IThread::Create: thread 0x%x already exists\n", id); |
| 379 thread->ref_++; | |
| 380 return thread; | |
| 381 } | 380 } |
| 382 | 381 |
| 383 // If not, can we create it? | 382 thread = new Thread(id, natp); |
| 384 if (create) { | 383 if (NULL == thread->handle_) { |
| 385 // If not add it to the map | 384 delete thread; |
| 386 thread = new Thread(id); | 385 return NULL; |
| 387 if (NULL == thread->handle_) { | |
| 388 delete thread; | |
| 389 return NULL; | |
| 390 } | |
| 391 | |
| 392 map[id] = thread; | |
| 393 return thread; | |
| 394 } | 386 } |
| 395 | 387 |
| 396 return NULL; | 388 map[id] = thread; |
| 389 return thread; |
| 390 } |
| 391 |
| 392 IThread* IThread::Acquire(uint32_t id) { |
| 393 MutexLock lock(ThreadGetLock()); |
| 394 Thread* thread; |
| 395 ThreadMap_t &map = *ThreadGetMap(); |
| 396 |
| 397 if (map.count(id) == 0) { |
| 398 NaClLog(LOG_FATAL, "IThread::Acquire: thread 0x%x does not exist\n", id); |
| 399 } |
| 400 |
| 401 thread = static_cast<Thread*>(map[id]); |
| 402 thread->ref_++; |
| 403 return thread; |
| 397 } | 404 } |
| 398 | 405 |
| 399 void IThread::Release(IThread *ithread) { | 406 void IThread::Release(IThread *ithread) { |
| 400 MutexLock lock(ThreadGetLock()); | 407 MutexLock lock(ThreadGetLock()); |
| 401 Thread* thread = static_cast<Thread*>(ithread); | 408 Thread* thread = static_cast<Thread*>(ithread); |
| 402 thread->ref_--; | 409 thread->ref_--; |
| 403 | 410 |
| 404 if (thread->ref_ == 0) { | 411 if (thread->ref_ == 0) { |
| 405 ThreadGetMap()->erase(thread->id_); | 412 ThreadGetMap()->erase(thread->id_); |
| 406 delete static_cast<IThread*>(thread); | 413 delete static_cast<IThread*>(thread); |
| 407 } | 414 } |
| 408 } | 415 } |
| 409 | 416 |
| 410 void IThread::SetExceptionCatch(IThread::CatchFunc_t func, void *cookie) { | 417 void IThread::SetExceptionCatch(IThread::CatchFunc_t func, void *cookie) { |
| 411 MutexLock lock(ThreadGetLock()); | 418 MutexLock lock(ThreadGetLock()); |
| 412 | 419 |
| 413 // Remove our old catch if there is one, this allows us to add again | 420 // Remove our old catch if there is one, this allows us to add again |
| 414 if (NULL != s_OldCatch) RemoveVectoredExceptionHandler(s_OldCatch); | 421 if (NULL != s_OldCatch) RemoveVectoredExceptionHandler(s_OldCatch); |
| 415 | 422 |
| 416 // Add the new one, at the front of the list | 423 // Add the new one, at the front of the list |
| 417 s_OldCatch = AddVectoredExceptionHandler(1, Thread::ExceptionCatch); | 424 s_OldCatch = AddVectoredExceptionHandler(1, Thread::ExceptionCatch); |
| 418 s_CatchFunc = func; | 425 s_CatchFunc = func; |
| 419 s_CatchCookie = cookie; | 426 s_CatchCookie = cookie; |
| 420 } | 427 } |
| 421 | 428 |
| 422 | 429 |
| 423 } // End of port namespace | 430 } // End of port namespace |
| 424 | 431 |
| OLD | NEW |