/* Generated automatically by jlpp - do not edit. */ #include static jakelib::lang::String* jakelib2_strings[] = {null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null}; // "Cannot create thread - error code " static jchar chars_jakelib2_str_0[] = {67,97,110,110,111,116,32,99,114,101,97,116,101,32,116,104,114,101,97,100,32,45,32,101,114,114,111,114,32,99,111,100,101,32}; // "Thread-" static jchar chars_jakelib2_str_1[] = {84,104,114,101,97,100,45}; // "Cannot create thread - error code " static jchar chars_jakelib2_str_2[] = {67,97,110,110,111,116,32,99,114,101,97,116,101,32,116,104,114,101,97,100,32,45,32,101,114,114,111,114,32,99,111,100,101,32}; // "Thread-" static jchar chars_jakelib2_str_3[] = {84,104,114,101,97,100,45}; // "main" static jchar chars_jakelib2_str_4[] = {109,97,105,110}; // "Cannot start thread - error code " static jchar chars_jakelib2_str_5[] = {67,97,110,110,111,116,32,115,116,97,114,116,32,116,104,114,101,97,100,32,45,32,101,114,114,111,114,32,99,111,100,101,32}; // "jakelib.lang.Thread.start" static jchar chars_jakelib2_str_6[] = {106,97,107,101,108,105,98,46,108,97,110,103,46,84,104,114,101,97,100,46,115,116,97,114,116}; // "Cannot create/start thread - error code " static jchar chars_jakelib2_str_7[] = {67,97,110,110,111,116,32,99,114,101,97,116,101,47,115,116,97,114,116,32,116,104,114,101,97,100,32,45,32,101,114,114,111,114,32,99,111,100,101,32}; // "jakelib.lang.Thread.start" static jchar chars_jakelib2_str_8[] = {106,97,107,101,108,105,98,46,108,97,110,103,46,84,104,114,101,97,100,46,115,116,97,114,116}; // "jakelib.lang.Thread.start" static jchar chars_jakelib2_str_9[] = {106,97,107,101,108,105,98,46,108,97,110,103,46,84,104,114,101,97,100,46,115,116,97,114,116}; // "Unable to set cancellation state for thread - error code " static jchar chars_jakelib2_str_10[] = {85,110,97,98,108,101,32,116,111,32,115,101,116,32,99,97,110,99,101,108,108,97,116,105,111,110,32,115,116,97,116,101,32,102,111,114,32,116,104,114,101,97,100,32,45,32,101,114,114,111,114,32,99,111,100,101,32}; // "Unable to set cancellation type for thread - error code " static jchar chars_jakelib2_str_11[] = {85,110,97,98,108,101,32,116,111,32,115,101,116,32,99,97,110,99,101,108,108,97,116,105,111,110,32,116,121,112,101,32,102,111,114,32,116,104,114,101,97,100,32,45,32,101,114,114,111,114,32,99,111,100,101,32}; // "" static jchar chars_jakelib2_str_12[] = {0}; // "jakelib.lang.Thread.yield" static jchar chars_jakelib2_str_13[] = {106,97,107,101,108,105,98,46,108,97,110,103,46,84,104,114,101,97,100,46,121,105,101,108,100}; // "" static jchar chars_jakelib2_str_14[] = {0}; // "jakelib.lang.Thread.join" static jchar chars_jakelib2_str_15[] = {106,97,107,101,108,105,98,46,108,97,110,103,46,84,104,114,101,97,100,46,106,111,105,110}; // "jakelib.lang.Thread.currentThread" static jchar chars_jakelib2_str_16[] = {106,97,107,101,108,105,98,46,108,97,110,103,46,84,104,114,101,97,100,46,99,117,114,114,101,110,116,84,104,114,101,97,100}; // "Cannot determine current thread" static jchar chars_jakelib2_str_17[] = {67,97,110,110,111,116,32,100,101,116,101,114,109,105,110,101,32,99,117,114,114,101,110,116,32,116,104,114,101,97,100}; // "jakelib.lang.Thread.currentThread" static jchar chars_jakelib2_str_18[] = {106,97,107,101,108,105,98,46,108,97,110,103,46,84,104,114,101,97,100,46,99,117,114,114,101,110,116,84,104,114,101,97,100}; #line 1 "lang/Thread.jlc" // -*- c++ -*- /* * Jakelib2 - General purpose C++ library * Copyright (C) 2001 Florian Wolff (florian@donuz.de) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: Thread.jlc,v 1.16 2003/10/07 17:42:10 florian Exp $ */ #include "jakelib2.h" #include "jakelib2/lang/Thread.h" #include "jakelib2/lang/Synchronizer.h" #include "jakelib2/lang/Integer.h" #include "jakelib2/lang/System.h" #include "jakelib2/util/ArrayList.h" #include "jakelib2/lang/StackTrace.h" using namespace jakelib::lang; using namespace jakelib::io; using namespace jakelib::util; JAKELIB_IMPLEMENT_CLASS_1("jakelib.lang.Thread", Thread, Object, Runnable); #ifdef HAVE_UNISTD_H # include #endif #ifdef JAKELIB_THREADS Mutex* Thread::globalThreadLock = null; #endif Thread* Thread::mainThread = null; int Thread::highestThreadNumber = 0; ArrayList *Thread::allThreads = null; #ifdef HAVE_PTHREADS pthread_key_t Thread::currentThreadKey; #endif #ifdef HAVE_WINTHREADS DWORD Thread::currentThreadKey; #endif /*****************************************************************************\ * Thread | *****************************************************************************/ #ifdef JAKELIB_THREADS Thread::Thread(jakelib::lang::String* name) { //stackTrace = new StackTrace(); state = THREAD_STATE_INIT; this->target = this; this->interruptFlag = false; #ifdef HAVE_WINTHREADS DWORD id; handle = CreateThread(null, 0, (LPTHREAD_START_ROUTINE)Thread::intThreadRun, this, CREATE_SUSPENDED, &id); if (handle == null) throw new IOException(JAKELIB_ONDEMAND(jakelib2_strings[0], new jakelib::lang::String(chars_jakelib2_str_0, 0, 34)) ->plus( (jlong)GetLastError() )->plus( JAKELIB_AT2("jakelib.lang.Thread.Thread"))); #endif Sentry sentry(globalThreadLock); threadNumber = highestThreadNumber++; if (name == NULL) this->name = JAKELIB_ONDEMAND(jakelib2_strings[1], new jakelib::lang::String(chars_jakelib2_str_1, 0, 7)) ->plus( threadNumber); else this->name = name; } Thread::Thread(Runnable* target, jakelib::lang::String* name) { //stackTrace = new StackTrace(); state = THREAD_STATE_INIT; this->target = target; this->interruptFlag = false; #ifdef HAVE_WINTHREADS handle = INVALID_HANDLE_VALUE; DWORD id; handle = CreateThread(null, 0, (LPTHREAD_START_ROUTINE)Thread::intThreadRun, target, CREATE_SUSPENDED, &id); if (handle == null) throw new IOException(JAKELIB_ONDEMAND(jakelib2_strings[2], new jakelib::lang::String(chars_jakelib2_str_2, 0, 34)) ->plus( (jlong)GetLastError() )->plus( JAKELIB_AT2("jakelib.lang.Thread.Thread"))); #endif Sentry sentry(globalThreadLock); threadNumber = highestThreadNumber++; if (name == NULL) this->name = JAKELIB_ONDEMAND(jakelib2_strings[3], new jakelib::lang::String(chars_jakelib2_str_3, 0, 7)) ->plus( threadNumber); else this->name = name; } #endif Thread::Thread(jboolean) { allThreads->add(this); //stackTrace = new StackTrace(); this->interruptFlag = false; #if defined(HAVE_PTHREADS) pthread_key_create(¤tThreadKey, null); pthread_setspecific(currentThreadKey, this); #endif #ifdef HAVE_WINTHREADS currentThreadKey = TlsAlloc(); TlsSetValue(currentThreadKey, this); #endif threadNumber = -1; name = JAKELIB_ONDEMAND(jakelib2_strings[4], new jakelib::lang::String(chars_jakelib2_str_4, 0, 4)); } /*****************************************************************************\ * run | *****************************************************************************/ void Thread::run() {} #ifdef JAKELIB_THREADS /*****************************************************************************\ * start | *****************************************************************************/ void Thread::start() { if (state != THREAD_STATE_INIT && state != THREAD_STATE_STOPPED) { throw new IllegalThreadStateException(); } state = THREAD_STATE_RUNNING; #if defined(HAVE_WINTHREADS) if (ResumeThread(handle) == 0xFFFFFFFF) throw new IOException(JAKELIB_ONDEMAND(jakelib2_strings[5], new jakelib::lang::String(chars_jakelib2_str_5, 0, 33)) ->plus( (jlong)GetLastError() )->plus( JAKELIB_AT2(JAKELIB_ONDEMAND(jakelib2_strings[6], new jakelib::lang::String(chars_jakelib2_str_6, 0, 25))))); #elif defined(HAVE_PTHREADS) int error = pthread_create(&threadInfo, null, Thread::voidThreadRun, this); if (error != 0) throw new IOException(JAKELIB_ONDEMAND(jakelib2_strings[7], new jakelib::lang::String(chars_jakelib2_str_7, 0, 40)) ->plus( error )->plus( JAKELIB_AT2(JAKELIB_ONDEMAND(jakelib2_strings[8], new jakelib::lang::String(chars_jakelib2_str_8, 0, 25))))); #else # warning "jakelib.lang.Thread.start not supported => Threads not supported!" throw new UnsupportedOperationException(JAKELIB_AT2(JAKELIB_ONDEMAND(jakelib2_strings[9], new jakelib::lang::String(chars_jakelib2_str_9, 0, 25)))); #endif } /*****************************************************************************\ * threadRun | *****************************************************************************/ #ifdef HAVE_WINTHREADS int Thread::intThreadRun (Thread* thread) { TlsSetValue(currentThreadKey, thread); thread->beforeRun(); thread->target->run(); thread->afterRun(); LocalFree((HLOCAL) thread); return 0; } #endif #ifdef HAVE_PTHREADS void* Thread::voidThreadRun(void* _thread) { int error; Thread* thread = (Thread*) _thread; error = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, null); if (error) throw new IOException(JAKELIB_ONDEMAND(jakelib2_strings[10], new jakelib::lang::String(chars_jakelib2_str_10, 0, 57)) ->plus( error )->plus( JAKELIB_AT2("jakelib.lang.Thread.threadRun"))); error = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, null); if (error) throw new IOException(JAKELIB_ONDEMAND(jakelib2_strings[11], new jakelib::lang::String(chars_jakelib2_str_11, 0, 56)) ->plus( error )->plus( JAKELIB_AT2("jakelib.lang.Thread.threadRun"))); pthread_setspecific(currentThreadKey, thread); thread->beforeRun(); thread->target->run(); thread->afterRun(); pthread_setspecific(currentThreadKey, null); return null; } #endif /*****************************************************************************\ * yield | *****************************************************************************/ void Thread::yield() { #if defined(HAVE_WINTHREADS) // FIXME: MSVC! //SwitchToThread(); ::Sleep(0); #elif defined(HAVE_PTHREADS) && defined(__USE_GNU) pthread_yield(); #elif defined(_POSIX_PRIORITY_SCHEDULING) sched_yield(); #else # warning "jakelib.lang.Thread.yield not supported." throw new UnsupportedOperationException(JAKELIB_ONDEMAND(jakelib2_strings[12], new jakelib::lang::String(chars_jakelib2_str_12, 0, 0)) ->plus( JAKELIB_AT2(JAKELIB_ONDEMAND(jakelib2_strings[13], new jakelib::lang::String(chars_jakelib2_str_13, 0, 25))))); #endif } /*****************************************************************************\ * join | *****************************************************************************/ void Thread::join() { if (interrupted()) { throw new InterruptedException(); } #if defined(HAVE_PTHREADS) pthread_join(threadInfo, null); #elif defined(HAVE_WINTHREADS) WaitForSingleObject(handle, INFINITE); #else # warning "jakelib.lang.Thread.join not supported." throw new UnsupportedOperationException(JAKELIB_ONDEMAND(jakelib2_strings[14], new jakelib::lang::String(chars_jakelib2_str_14, 0, 0)) ->plus( JAKELIB_AT2(JAKELIB_ONDEMAND(jakelib2_strings[15], new jakelib::lang::String(chars_jakelib2_str_15, 0, 24))))); #endif } #endif /*****************************************************************************\ * currentThread | *****************************************************************************/ Thread* Thread::currentThread() { #ifdef JAKELIB_THREADS Thread *thread; # if defined(HAVE_PTHREADS) thread = (Thread*)pthread_getspecific(currentThreadKey); # elif defined(HAVE_WINTHREADS) thread = (Thread*) TlsGetValue(currentThreadKey); # else # warning "jakelib.lang.Thread.currentThread not supported." throw new UnsupportedOperationException(JAKELIB_AT2(JAKELIB_ONDEMAND(jakelib2_strings[16], new jakelib::lang::String(chars_jakelib2_str_16, 0, 33)))); # endif if (thread != null) return thread; else throw new IllegalThreadStateException(JAKELIB_ONDEMAND(jakelib2_strings[17], new jakelib::lang::String(chars_jakelib2_str_17, 0, 31)) ->plus( JAKELIB_AT2(JAKELIB_ONDEMAND(jakelib2_strings[18], new jakelib::lang::String(chars_jakelib2_str_18, 0, 33))))); #else return mainThread; #endif } /*****************************************************************************\ * getName | *****************************************************************************/ String* Thread::getName() { return name; } /*****************************************************************************\ * toString | *****************************************************************************/ String* Thread::toString() { StringBuffer buf; buf.append('['); buf.append(name); buf.append(']'); return buf.toString(); } /*****************************************************************************\ * hashCode | *****************************************************************************/ int Thread::hashCode() { return threadNumber + 1; } /*****************************************************************************\ * initThreadClass | *****************************************************************************/ void Thread::initThreadClass() { #ifdef JAKELIB_THREADS globalThreadLock = new Mutex(); #endif allThreads = new ArrayList(50); mainThread = new Thread(true); } // /*****************************************************************************\ // * getStackTrace | // *****************************************************************************/ // StackTrace* Thread::getStackTrace() // { // return stackTrace; // } // /*****************************************************************************\ // * dumpStack | // *****************************************************************************/ // void Thread::dumpStack() // { // System::out->println(stackTrace); // } /*****************************************************************************\ * sleep | *****************************************************************************/ void Thread::sleep(jlong millis) { if (interrupted()) { throw new InterruptedException(); } #if defined(JAKELIB_WIN32API) Sleep((DWORD) millis); #else usleep(millis * 1000); #endif } #ifdef JAKELIB_THREADS /*****************************************************************************\ * afterRun | *****************************************************************************/ void Thread::afterRun() { Sentry sentry(globalThreadLock); allThreads->remove(this); //stackTrace->destroy(); //stackTrace = null; //printf("Thread::afterRun: %s\n", JAKELIB_LATIN1(allThreads->toString())); } /*****************************************************************************\ * beforeRun | *****************************************************************************/ void Thread::beforeRun() { Sentry sentry(globalThreadLock); allThreads->add(this); //printf("Thread::beforeRun: %s\n", JAKELIB_LATIN1(allThreads->toString())); } /*****************************************************************************\ * interrupt | *****************************************************************************/ void Thread::interrupt() { interruptFlag = true; } /*****************************************************************************\ * isInterrupted | *****************************************************************************/ jboolean Thread::isInterrupted() { return interruptFlag; } /*****************************************************************************\ * interrupted | *****************************************************************************/ jboolean Thread::interrupted() { Thread *t = currentThread(); jboolean flag = t->interruptFlag; t->interruptFlag = false; return flag; } #endif