Chromium Code Reviews| 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_ERROR, "IThread::Create: thread 0x%x already exists\n", id); |
|
Mark Seaborn
2012/05/07 21:56:49
Ditto
eaeltsin
2012/05/08 11:10:19
Done.
| |
| 379 thread->ref_++; | 380 return NULL; |
| 380 return thread; | |
| 381 } | 381 } |
| 382 | 382 |
| 383 // If not, can we create it? | 383 thread = new Thread(id, natp); |
| 384 if (create) { | 384 if (NULL == thread->handle_) { |
| 385 // If not add it to the map | 385 delete thread; |
|
Mark Seaborn
2012/05/07 21:56:49
FYI, this isn't consistent with the posix implemen
eaeltsin
2012/05/08 11:10:19
This is the old code, kept as is.
Anyway, this co
| |
| 386 thread = new Thread(id); | 386 return NULL; |
| 387 if (NULL == thread->handle_) { | |
| 388 delete thread; | |
| 389 return NULL; | |
| 390 } | |
| 391 | |
| 392 map[id] = thread; | |
| 393 return thread; | |
| 394 } | 387 } |
| 395 | 388 |
| 396 return NULL; | 389 map[id] = thread; |
| 390 return thread; | |
| 391 } | |
| 392 | |
| 393 IThread* IThread::Acquire(uint32_t id) { | |
| 394 MutexLock lock(ThreadGetLock()); | |
| 395 Thread* thread; | |
| 396 ThreadMap_t &map = *ThreadGetMap(); | |
| 397 | |
| 398 if (map.count(id) == 0) { | |
| 399 NaClLog(LOG_ERROR, "IThread::Acquire: thread 0x%x does not exist\n", id); | |
| 400 return NULL; | |
| 401 } | |
| 402 | |
| 403 thread = static_cast<Thread*>(map[id]); | |
| 404 thread->ref_++; | |
| 405 return thread; | |
| 397 } | 406 } |
| 398 | 407 |
| 399 void IThread::Release(IThread *ithread) { | 408 void IThread::Release(IThread *ithread) { |
| 400 MutexLock lock(ThreadGetLock()); | 409 MutexLock lock(ThreadGetLock()); |
| 401 Thread* thread = static_cast<Thread*>(ithread); | 410 Thread* thread = static_cast<Thread*>(ithread); |
| 402 thread->ref_--; | 411 thread->ref_--; |
| 403 | 412 |
| 404 if (thread->ref_ == 0) { | 413 if (thread->ref_ == 0) { |
| 405 ThreadGetMap()->erase(thread->id_); | 414 ThreadGetMap()->erase(thread->id_); |
| 406 delete static_cast<IThread*>(thread); | 415 delete static_cast<IThread*>(thread); |
| 407 } | 416 } |
| 408 } | 417 } |
| 409 | 418 |
| 410 void IThread::SetExceptionCatch(IThread::CatchFunc_t func, void *cookie) { | 419 void IThread::SetExceptionCatch(IThread::CatchFunc_t func, void *cookie) { |
| 411 MutexLock lock(ThreadGetLock()); | 420 MutexLock lock(ThreadGetLock()); |
| 412 | 421 |
| 413 // Remove our old catch if there is one, this allows us to add again | 422 // Remove our old catch if there is one, this allows us to add again |
| 414 if (NULL != s_OldCatch) RemoveVectoredExceptionHandler(s_OldCatch); | 423 if (NULL != s_OldCatch) RemoveVectoredExceptionHandler(s_OldCatch); |
| 415 | 424 |
| 416 // Add the new one, at the front of the list | 425 // Add the new one, at the front of the list |
| 417 s_OldCatch = AddVectoredExceptionHandler(1, Thread::ExceptionCatch); | 426 s_OldCatch = AddVectoredExceptionHandler(1, Thread::ExceptionCatch); |
| 418 s_CatchFunc = func; | 427 s_CatchFunc = func; |
| 419 s_CatchCookie = cookie; | 428 s_CatchCookie = cookie; |
| 420 } | 429 } |
| 421 | 430 |
| 422 | 431 |
| 423 } // End of port namespace | 432 } // End of port namespace |
| 424 | 433 |
| OLD | NEW |