Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: base/threading/platform_thread_posix.cc

Issue 1150563002: base/threading: Lazy thread startup for pthreads (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase, and do not use private handle_ Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/threading/platform_thread.h" 5 #include "base/threading/platform_thread.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <pthread.h> 8 #include <pthread.h>
9 #include <sched.h> 9 #include <sched.h>
10 #include <sys/resource.h> 10 #include <sys/resource.h>
(...skipping 18 matching lines...) Expand all
29 29
30 void InitThreading(); 30 void InitThreading();
31 void InitOnThread(); 31 void InitOnThread();
32 void TerminateOnThread(); 32 void TerminateOnThread();
33 size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes); 33 size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes);
34 34
35 namespace { 35 namespace {
36 36
37 struct ThreadParams { 37 struct ThreadParams {
38 ThreadParams() 38 ThreadParams()
39 : delegate(NULL), 39 : delegate(NULL), joinable(false), priority(ThreadPriority::NORMAL) {}
40 joinable(false),
41 priority(ThreadPriority::NORMAL),
42 handle(NULL),
43 handle_set(false, false) {
44 }
45 40
46 PlatformThread::Delegate* delegate; 41 PlatformThread::Delegate* delegate;
47 bool joinable; 42 bool joinable;
48 ThreadPriority priority; 43 ThreadPriority priority;
49 PlatformThreadHandle* handle;
50 WaitableEvent handle_set;
51 }; 44 };
52 45
53 void* ThreadFunc(void* params) { 46 void* ThreadFunc(void* params) {
47 CHECK(params);
54 base::InitOnThread(); 48 base::InitOnThread();
55 ThreadParams* thread_params = static_cast<ThreadParams*>(params); 49 scoped_ptr<ThreadParams> thread_params(static_cast<ThreadParams*>(params));
56 50
57 PlatformThread::Delegate* delegate = thread_params->delegate; 51 PlatformThread::Delegate* delegate = thread_params->delegate;
58 if (!thread_params->joinable) 52 if (!thread_params->joinable)
59 base::ThreadRestrictions::SetSingletonAllowed(false); 53 base::ThreadRestrictions::SetSingletonAllowed(false);
60 54
61 if (thread_params->priority != ThreadPriority::NORMAL) 55 if (thread_params->priority != ThreadPriority::NORMAL)
62 PlatformThread::SetCurrentThreadPriority(thread_params->priority); 56 PlatformThread::SetCurrentThreadPriority(thread_params->priority);
63 57
64 // Stash the id in the handle so the calling thread has a complete
65 // handle, and unblock the parent thread.
66 *(thread_params->handle) = PlatformThreadHandle(pthread_self());
67 thread_params->handle_set.Signal();
68
69 ThreadIdNameManager::GetInstance()->RegisterThread( 58 ThreadIdNameManager::GetInstance()->RegisterThread(
70 PlatformThread::CurrentHandle().platform_handle(), 59 PlatformThread::CurrentHandle().platform_handle(),
71 PlatformThread::CurrentId()); 60 PlatformThread::CurrentId());
72 61
73 delegate->ThreadMain(); 62 delegate->ThreadMain();
74 63
75 ThreadIdNameManager::GetInstance()->RemoveName( 64 ThreadIdNameManager::GetInstance()->RemoveName(
76 PlatformThread::CurrentHandle().platform_handle(), 65 PlatformThread::CurrentHandle().platform_handle(),
77 PlatformThread::CurrentId()); 66 PlatformThread::CurrentId());
78 67
79 base::TerminateOnThread(); 68 base::TerminateOnThread();
80 return NULL; 69 return NULL;
81 } 70 }
82 71
83 bool CreateThread(size_t stack_size, bool joinable, 72 bool CreateThread(size_t stack_size,
73 bool joinable,
84 PlatformThread::Delegate* delegate, 74 PlatformThread::Delegate* delegate,
85 PlatformThreadHandle* thread_handle, 75 PlatformThreadHandle* thread_handle,
86 ThreadPriority priority) { 76 ThreadPriority priority) {
77 CHECK(thread_handle);
87 base::InitThreading(); 78 base::InitThreading();
88 79
89 bool success = false;
90 pthread_attr_t attributes; 80 pthread_attr_t attributes;
91 pthread_attr_init(&attributes); 81 pthread_attr_init(&attributes);
92 82
93 // Pthreads are joinable by default, so only specify the detached 83 // Pthreads are joinable by default, so only specify the detached
94 // attribute if the thread should be non-joinable. 84 // attribute if the thread should be non-joinable.
95 if (!joinable) { 85 if (!joinable)
96 pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); 86 pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
97 }
98 87
99 // Get a better default if available. 88 // Get a better default if available.
100 if (stack_size == 0) 89 if (stack_size == 0)
101 stack_size = base::GetDefaultThreadStackSize(attributes); 90 stack_size = base::GetDefaultThreadStackSize(attributes);
102 91
103 if (stack_size > 0) 92 if (stack_size > 0)
104 pthread_attr_setstacksize(&attributes, stack_size); 93 pthread_attr_setstacksize(&attributes, stack_size);
105 94
106 ThreadParams params; 95 scoped_ptr<ThreadParams> params(new ThreadParams);
107 params.delegate = delegate; 96 params->delegate = delegate;
108 params.joinable = joinable; 97 params->joinable = joinable;
109 params.priority = priority; 98 params->priority = priority;
110 params.handle = thread_handle;
111 99
112 pthread_t handle; 100 pthread_t handle;
113 int err = pthread_create(&handle, 101 int err =
114 &attributes, 102 pthread_create(&handle, &attributes, ThreadFunc, params.get());
115 ThreadFunc, 103 bool success = !err;
116 &params); 104 if (success) {
117 success = !err; 105 // ThreadParams should be deleted on the created thread after used.
118 if (!success) { 106 ThreadParams* unused_params = params.release();
119 // Value of |handle| is undefined if pthread_create fails. 107 ALLOW_UNUSED_LOCAL(unused_params);
kinuko 2015/07/02 14:23:35 nit: ignore_result(param.release()) would work
Takashi Toyoshima 2015/07/03 04:31:35 Done.
108 } else {
109 // Value of |thread_handle| is undefined if pthread_create fails.
Takashi Toyoshima 2015/07/02 13:57:50 Oops, self review note: s/thread_handle/handle/.
Takashi Toyoshima 2015/07/03 04:31:35 Done.
120 handle = 0; 110 handle = 0;
121 errno = err; 111 errno = err;
122 PLOG(ERROR) << "pthread_create"; 112 PLOG(ERROR) << "pthread_create";
123 } 113 }
114 *thread_handle = PlatformThreadHandle(handle);
124 115
125 pthread_attr_destroy(&attributes); 116 pthread_attr_destroy(&attributes);
126 117
127 // Don't let this call complete until the thread id
128 // is set in the handle.
129 if (success)
130 params.handle_set.Wait();
131 CHECK_EQ(handle, thread_handle->platform_handle());
132
133 return success; 118 return success;
134 } 119 }
135 120
136 } // namespace 121 } // namespace
137 122
138 // static 123 // static
139 PlatformThreadId PlatformThread::CurrentId() { 124 PlatformThreadId PlatformThread::CurrentId() {
140 // Pthreads doesn't have the concept of a thread ID, so we have to reach down 125 // Pthreads doesn't have the concept of a thread ID, so we have to reach down
141 // into the kernel. 126 // into the kernel.
142 #if defined(OS_MACOSX) 127 #if defined(OS_MACOSX)
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 return ThreadPriority::NORMAL; 261 return ThreadPriority::NORMAL;
277 } 262 }
278 263
279 return internal::NiceValueToThreadPriority(nice_value); 264 return internal::NiceValueToThreadPriority(nice_value);
280 #endif // !defined(OS_NACL) 265 #endif // !defined(OS_NACL)
281 } 266 }
282 267
283 #endif // !defined(OS_MACOSX) 268 #endif // !defined(OS_MACOSX)
284 269
285 } // namespace base 270 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698