2 * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
3 * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
4 * (C) 2007 Eric Seidel <eric@webkit.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #import "JavaScriptThreading.h"
33 #import <CoreFoundation/CoreFoundation.h>
34 #import <JavaScriptCore/JavaScriptCore.h>
36 #import <wtf/Assertions.h>
38 static pthread_mutex_t javaScriptThreadsMutex = PTHREAD_MUTEX_INITIALIZER;
39 static bool javaScriptThreadsShouldTerminate;
41 static const int javaScriptThreadsCount = 4;
42 static CFMutableDictionaryRef javaScriptThreads()
44 assert(pthread_mutex_trylock(&javaScriptThreadsMutex) == EBUSY);
45 static CFMutableDictionaryRef staticJavaScriptThreads;
46 if (!staticJavaScriptThreads)
47 staticJavaScriptThreads = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
48 return staticJavaScriptThreads;
51 // Loops forever, running a script and randomly respawning, until
52 // javaScriptThreadsShouldTerminate becomes true.
53 void* runJavaScriptThread(void* arg)
55 const char* const script =
57 "for (var i = 0; i < 10; i++) {"
58 " array.push(String(i));"
62 JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);
63 JSStringRef scriptRef = JSStringCreateWithUTF8CString(script);
65 JSValueRef exception = NULL;
66 JSEvaluateScript(ctx, scriptRef, NULL, NULL, 0, &exception);
69 JSGlobalContextRelease(ctx);
70 JSStringRelease(scriptRef);
72 JSGarbageCollect(ctx);
74 pthread_mutex_lock(&javaScriptThreadsMutex);
76 // Check for cancellation.
77 if (javaScriptThreadsShouldTerminate) {
78 pthread_mutex_unlock(&javaScriptThreadsMutex);
82 // Respawn probabilistically.
83 if (random() % 5 == 0) {
85 pthread_create(&pthread, NULL, &runJavaScriptThread, NULL);
86 pthread_detach(pthread);
88 CFDictionaryRemoveValue(javaScriptThreads(), pthread_self());
89 CFDictionaryAddValue(javaScriptThreads(), pthread, NULL);
91 pthread_mutex_unlock(&javaScriptThreadsMutex);
95 pthread_mutex_unlock(&javaScriptThreadsMutex);
99 void startJavaScriptThreads()
101 pthread_mutex_lock(&javaScriptThreadsMutex);
103 for (int i = 0; i < javaScriptThreadsCount; i++) {
105 pthread_create(&pthread, NULL, &runJavaScriptThread, NULL);
106 pthread_detach(pthread);
107 CFDictionaryAddValue(javaScriptThreads(), pthread, NULL);
110 pthread_mutex_unlock(&javaScriptThreadsMutex);
113 void stopJavaScriptThreads()
115 pthread_mutex_lock(&javaScriptThreadsMutex);
117 javaScriptThreadsShouldTerminate = true;
119 pthread_t* pthreads[javaScriptThreadsCount] = { 0 };
120 ASSERT(CFDictionaryGetCount(javaScriptThreads()) == javaScriptThreadsCount);
121 CFDictionaryGetKeysAndValues(javaScriptThreads(), (const void**)pthreads, 0);
123 pthread_mutex_unlock(&javaScriptThreadsMutex);
125 for (int i = 0; i < javaScriptThreadsCount; i++) {
126 pthread_t* pthread = pthreads[i];
127 pthread_join(*pthread, 0);