diff --git a/.vscode/.cmaketools.json b/.vscode/.cmaketools.json new file mode 100644 index 00000000..e8a5846b --- /dev/null +++ b/.vscode/.cmaketools.json @@ -0,0 +1,5 @@ +{ + "variant": null, + "activeEnvironments": [], + "codeModel": null +} \ No newline at end of file diff --git a/library/Java/Lang/Runnable/Runnable.hpp b/library/Java/Lang/Runnable/Runnable.hpp index 25670e57..7da6a452 100755 --- a/library/Java/Lang/Runnable/Runnable.hpp +++ b/library/Java/Lang/Runnable/Runnable.hpp @@ -31,7 +31,7 @@ namespace Java { namespace Lang { class Runnable { public: - virtual void run() const = 0; + virtual void run() = 0; }; } } diff --git a/library/Java/Lang/String/String.hpp b/library/Java/Lang/String/String.hpp old mode 100755 new mode 100644 index cbc482ed..dd7a3a06 --- a/library/Java/Lang/String/String.hpp +++ b/library/Java/Lang/String/String.hpp @@ -108,22 +108,23 @@ namespace Java { */ String(); - /** + /** * Initializes a newly created String object * so that it represents the same sequence of characters as the argument. * * @param target */ - String(const String &target); + String(const String &target); - /** + /** * Constructs a new String by decoding the specified array of bytes. * * @param byteArray */ + String(Array byteArray); - /** + /** * Allocates a new String that contains the sequence * of characters currently contained in the StringBuilder. * @@ -131,7 +132,7 @@ namespace Java { */ String(const StringBuilder &stringBuilder); - /** + /** * Allocates a new String so that it represents the sequence * of characters currently contained in the character array argument. * @@ -139,7 +140,7 @@ namespace Java { */ String(Array charArray); - /** + /** * Allocates a new String that contains the sequence * of characters currently contained in the StringBuffer. * @@ -147,27 +148,27 @@ namespace Java { */ String(const StringBuffer &stringBuffer); - /** + /** * Constructs a new String by decoding the specified array of bytes * using the specified charset. * * @param byteArray * @param charsetName */ - // TODO (anhnt) need CharSet - // String(Array byteArray, String charsetName); + // TODO (anhnt) need CharSet + // String(Array byteArray, String charsetName); - /** + /** * Constructs a new String by decoding the specified array of bytes * using the specified charset. * * @param byteArray * @param charset */ - // TODO (anhnt) need CharSet - // String(Array byteArray, Charset charset) + // TODO (anhnt) need CharSet + // String(Array byteArray, Charset charset) - /** + /** * Allocates a new String that contains characters * from a subarray of the character array argument. * @@ -179,7 +180,7 @@ namespace Java { */ String(Array charArray, int offset, int count); - /** + /** * Allocates a new String that contains characters * from a subarray of the Unicode code point array argument. * @@ -191,10 +192,10 @@ namespace Java { * @throw IndexOutOfBoundsException If the offset and count * arguments index characters outside the bounds of the codePoints array */ - // TODO (anhnt) need CharSet - // String(Array codePoints, int offset, int count); + // TODO (anhnt) need CharSet + // String(Array codePoints, int offset, int count); - /** + /** * Constructs a new String by decoding the specified * subarray of bytes using the platform's default charset. * @@ -206,7 +207,7 @@ namespace Java { */ String(Array byteArray, int offset, int length); - /** + /** * Constructs a new String by decoding the specified * subarray of bytes using the specified charset * @@ -217,10 +218,10 @@ namespace Java { * @throw IndexOutOfBoundsException If the offset and length arguments index * characters outside the bounds of the bytes array */ - // TODO (anhnt) need CharSet - // String(Array &byteArray, int offset, int length, Charset charset); + // TODO (anhnt) need CharSet + // String(Array &byteArray, int offset, int length, Charset charset); - /** + /** * Constructs a new String by decoding the specified * subarray of bytes using the specified charset. * @@ -232,8 +233,8 @@ namespace Java { * @throw IndexOutOfBoundsException If the offset and length arguments index * characters outside the bounds of the bytes array */ - // TODO (anhnt) need CharSet - // String(Array &byteArray, int offset, int length, String charsetName); + // TODO (anhnt) need CharSet + // String(Array &byteArray, int offset, int length, String charsetName); /** * Construct a new String from specific string @@ -253,7 +254,7 @@ namespace Java { this->original = std::string(target); } - /** + /** * Construct a new String from specific std::string * * @param target @@ -262,7 +263,7 @@ namespace Java { this->original = targetString; } - /** + /** * Construct a new String from char array with specific length * * @param original @@ -270,7 +271,7 @@ namespace Java { */ String(string target, int length); - /** + /** * Destructor */ ~String(); @@ -294,7 +295,7 @@ namespace Java { */ int getSize() const; - /** + /** * String character at index * * @param index @@ -302,25 +303,26 @@ namespace Java { */ char charAt(int index) const override; - /** + /** * Returns the character (Unicode code point) at the specified index. * * @param index * @return int */ + // TODO (anhnt) need Character // int codePointAt(int index); - /** + /** * Returns the character (Unicode code point) before the specified index. * * @param index * @return int */ - // TODO (anhnt) need Character - // int codePointBefore(int index); + // TODO (anhnt) need Character + // int codePointBefore(int index); - /** + /** * Returns the number of Unicode code points * in the specified text range of this String. * @@ -328,17 +330,17 @@ namespace Java { * @param endIndex * @return int */ - // TODO (anhnt) need Character - // int codePointCount(int beginIndex, int endIndex); + // TODO (anhnt) need Character + // int codePointCount(int beginIndex, int endIndex); - /** + /** * Clone to new object * * @return String */ String clone(); - /** + /** * String compare to another string * * @param anotherString @@ -350,7 +352,7 @@ namespace Java { */ int compareTo(const String &anotherString) const override; - /** + /** * String compare with another String but ignore case * * @param targetString @@ -363,7 +365,6 @@ namespace Java { */ int compareToIgnoreCase(const String &targetString) const; - /** * String concatenation * @@ -372,7 +373,7 @@ namespace Java { */ String concat(String target); - /** + /** * Find substring inside this String * * @param charSequence @@ -380,7 +381,7 @@ namespace Java { */ boolean contains(const CharSequence &charSequence); - /** + /** * Compares this String to the specified CharSequence. * The result is true if and only if this String represents * the same sequence of char values as the specified sequence. @@ -390,7 +391,7 @@ namespace Java { */ boolean contentEquals(const CharSequence &charSequence); - /** + /** * Returns the String representation of the char array argument. * The contents of the character array are copied; * subsequent modification of the character array does not affect the returned string. @@ -400,7 +401,7 @@ namespace Java { */ static String copyValueOf(Array &charArray); - /** + /** * Returns the String representation of a specific subarray of the char array argument. * * @param charArray @@ -413,7 +414,7 @@ namespace Java { */ static String copyValueOf(Array &charArray, int offset, int count); - /** + /** * String endswith a suffix * * @param suffixString @@ -423,7 +424,7 @@ namespace Java { */ boolean endsWith(const String &suffixString) const; - /** + /** * Compares this String to the specified object. * * @param T @@ -439,14 +440,14 @@ namespace Java { return false; } - /** + /** * Compares this String to another String, ignoring case considerations. * * @param anotherString * @return true if the given object represents a String equivalent * to this string, false otherwise, ignoring case considerations */ - boolean equalsIgnoreCase(String anotherString); + boolean equalsIgnoreCase(String anotherString); /** * String hash code @@ -461,34 +462,34 @@ namespace Java { * @param charArray * @return String */ - static String fromCharArray(Array &charArray); + static String fromCharArray(Array &charArray); - /** + /** * Get byte array from this String * * @return Array */ Array getBytes() const; - /** + /** * Encodes this String into a sequence of bytes using the named charset, * storing the result into a new byte array. * * @param charSetName * @return */ - // Array getBytes(String charSetName) const; + // Array getBytes(String charSetName) const; - /** + /** * Encodes this String into a sequence of bytes using the charset, * storing the result into a new byte array. * * @param charSet * @return */ - // Array getBytes(CharSet charSet) const; + // Array getBytes(CharSet charSet) const; - /** + /** * Copies characters from this String into the destination character array. * * @param sourceBegin @@ -502,10 +503,10 @@ namespace Java { * destinationBegin is negative * destinationBegin + (srcEnd - srcBegin) is larger than destination.length */ - void getChars(int sourceBegin, int sourceEnd, - Array &destination, int destinationBegin); + void getChars(int sourceBegin, int sourceEnd, + Array &destination, int destinationBegin); - /** + /** * Get char to String * This function use for class UUID and Long * @@ -514,7 +515,7 @@ namespace Java { */ String getStringFromIndex(int index) const; - /** + /** * Returns the index within this String * of the first occurrence of the specified character. * @@ -524,7 +525,7 @@ namespace Java { */ int indexOf(int character) const; - /** + /** * Returns the index within this String * of the first occurrence of the specified String. * @@ -532,9 +533,9 @@ namespace Java { * @return index of the first occurrence of the specified substring, * or -1 if there is no such occurrence. */ - int indexOf(String subString) const; + int indexOf(String subString) const; - /** + /** * Returns the index within this String * of the first occurrence of the specified character, * starting the search at the specified index. @@ -546,7 +547,7 @@ namespace Java { */ int indexOf(int character, int fromIndex) const; - /** + /** * Returns the index within this string * of the first occurrence of the specified String. * starting the search at the specified index. @@ -558,14 +559,14 @@ namespace Java { */ int indexOf(String subString, int fromIndex) const; - /** + /** * Determine if this String is empty * * @return true if, and only if, length() is 0. */ boolean isEmpty() const; - /** + /** * Returns a new String composed of copies of the CharSequence elements * joined together * @@ -589,7 +590,7 @@ namespace Java { return result; } - /** + /** * Returns the index within this string of the last occurrence * of the specified character * @@ -599,7 +600,7 @@ namespace Java { */ int lastIndexOf(int character); - /** + /** * Returns the index within this string of the last occurrence * of the specified character, * searching backward starting at the specified index. @@ -611,7 +612,7 @@ namespace Java { */ int lastIndexOf(int character, int fromIndex); - /** + /** * Returns the index within this string of the last occurrence * of the specified substring * @@ -621,7 +622,7 @@ namespace Java { */ int lastIndexOf(String subString) const; - /** + /** * Returns the index within this string of the last occurrence * of the specified substring, * searching backward starting at the specified index. @@ -633,7 +634,7 @@ namespace Java { */ int lastIndexOf(String subString, int fromIndex) const; - /** + /** * Returns the length of this string * * @return int @@ -642,7 +643,7 @@ namespace Java { return this->original.size(); } - /** + /** * Tells whether or not this string matches the given regular expression. * * @param regex @@ -651,10 +652,11 @@ namespace Java { * @return true if, and only if, this string matches * the given regular expression */ + // TODO (anhnt) need Pattern // boolean matches(String regex) const; - /** + /** * Returns the index within this String that is offset * from the given index by codePointOffset code points * @@ -668,10 +670,10 @@ namespace Java { * the absolute value of codePointOffset code points. * @return the index within this String */ - // TODO (anhnt) need Character - // int offsetByCodePoints(int index, int codePointOffset); + // TODO (anhnt) need Character + // int offsetByCodePoints(int index, int codePointOffset); - /** + /** * Tests if two string regions are equal. * * @param thisOffset @@ -681,10 +683,10 @@ namespace Java { * @return true if the specified subregion of this String exactly * matches the specified subregion of the String argument; false otherwise. */ - boolean regionMatches(int thisOffset, - String otherString, int otherOffset, int len); + boolean regionMatches(int thisOffset, + String otherString, int otherOffset, int len); - /** + /** * Tests if two string regions are equal. * * @param ignoreCase @@ -696,10 +698,10 @@ namespace Java { * subregion of the String argument; false otherwise. * Whether the matching is exact or case insensitive depends on the ignoreCase argument. */ - boolean regionMatches(boolean ignoreCase, int thisOffset, - String otherString, int otherOffset, int len); + boolean regionMatches(boolean ignoreCase, int thisOffset, + String otherString, int otherOffset, int len); - /** + /** * Returns a string resulting from replacing all occurrences * of oldChar in this String with newChar. * @@ -710,7 +712,7 @@ namespace Java { */ String replace(char oldChar, char newChar) const; - /** + /** * Replaces each substring of this string that matches the literal * target sequence with the specified literal replacement sequence. * The replacement proceeds from the beginning of the string to the end. @@ -719,9 +721,9 @@ namespace Java { * @param replacement * @return The resulting String */ - String replace(CharSequence &target, CharSequence &replacement) const; + String replace(CharSequence &target, CharSequence &replacement) const; - /** + /** * Replaces each substring of this string that matches * the given regular expression with the given replacement. * @@ -733,7 +735,7 @@ namespace Java { */ String replaceAll(String regex, String replacement) const; - /** + /** * Replaces the first substring of this string that matches * the given regular expression with the given replacement. * @@ -745,7 +747,7 @@ namespace Java { */ String replaceFirst(String regex, String replacement) const; - /** + /** * Splits this String around matches of the given regular expression. * * @param regex @@ -756,7 +758,7 @@ namespace Java { */ Array split(String regex) const; - /** + /** * Splits this string around matches of the given regular expression. * * @param regex @@ -768,7 +770,7 @@ namespace Java { */ Array split(String regex, int limit) const; - /** + /** * Tests if this string starts with the specified prefix. * * @param prefix @@ -777,7 +779,7 @@ namespace Java { */ boolean startsWith(String prefix) const; - /** + /** * Tests if the substring of this string beginning * at the specified index starts with the specified prefix. * @@ -790,7 +792,7 @@ namespace Java { */ boolean startsWith(String prefix, int thisOffset) const; - /** + /** * Returns a character sequence that is a subsequence of this sequence. * * @param beginIndex @@ -799,9 +801,9 @@ namespace Java { * if endIndex is greater than length(), or if beginIndex is greater than endIndex * @return the specified subsequence. */ - // CharSequence subSequence(int beginIndex, int endIndex); + // CharSequence subSequence(int beginIndex, int endIndex); - /** + /** * Returns a String that is a substring of this String. * The substring begins with the character at the specified * index and extends to the end of this string. @@ -811,9 +813,9 @@ namespace Java { * or larger than the length of this String object. * @return the specified substring as a String. */ - String subString(int beginIndex) const; + String subString(int beginIndex) const; - /** + /** * Returns a string that is a substring of this string. * The substring begins at the specified beginIndex * and extends to the character at index endIndex - 1 @@ -825,16 +827,16 @@ namespace Java { * or beginIndex is larger than endIndex. * @return the specified substring as a String. */ - String subString(int beginIndex, int endIndex) const; + String subString(int beginIndex, int endIndex) const; - /** + /** * Converts this string to a new character array. * * @return a newly allocated character array contain */ Array toCharArray() const; - /** + /** * Converts all of the characters in this String to lower case * using the rules of the default locale. * @@ -869,7 +871,7 @@ namespace Java { // TODO need Locale // String toUpperCase(Locale locale); - /** + /** * Returns a String whose value is this string, with any leading * * and trailing whitespace removed. @@ -885,14 +887,14 @@ namespace Java { */ string toCharPointer() const; - /** + /** * Return a String a string contain value of this String * * @return a String contain value of this String */ String toString() const; - /** + /** * Returns the String representation of the boolean argument. * * @param boolValue @@ -901,7 +903,7 @@ namespace Java { */ static String valueOf(boolean boolValue); - /** + /** * Returns the String representation of the char argument. * * @param charValue @@ -909,7 +911,7 @@ namespace Java { */ static String valueOf(char charValue); - /** + /** * Returns the String representation of the string argument. * * @param stringValue @@ -941,7 +943,7 @@ namespace Java { */ static String valueOf(short shortValue); - /** + /** * Returns the String representation of the int argument. * * @param intValue @@ -949,7 +951,7 @@ namespace Java { */ static String valueOf(int intValue); - /** + /** * Returns the String representation of the long argument. * * @param longValue @@ -965,7 +967,7 @@ namespace Java { */ static String valueOf(float floatValue); - /** + /** * Returns the String representation of the double argument. * * @param doubleValue @@ -1171,7 +1173,7 @@ namespace Java { return result; } - /** + /** * Format string * * @param format diff --git a/library/Java/Lang/Thread/Thread.cpp b/library/Java/Lang/Thread/Thread.cpp index f59936d4..1cbd011e 100755 --- a/library/Java/Lang/Thread/Thread.cpp +++ b/library/Java/Lang/Thread/Thread.cpp @@ -24,115 +24,113 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include #include "Thread.hpp" +#include "../InterruptedException/InterruptedException.hpp" -//using namespace Java::Lang; -// -//Thread::Thread() { -// this->target = nullptr; -// this->threadName = stringCopy(""); -//} -// -//Thread::Thread(Runnable &target2) { -// this->target = &target2; -// this->threadName = stringCopy(""); -//} -// -//Thread::Thread(Runnable &target2, String name) { -// this->target = &target2; -// this->threadName = stringCopy(name.toString()); -//} -// -//Thread::Thread(String name) { -// this->target = nullptr; -// this->threadName = stringCopy(name.toString()); -//} -// -//Thread::~Thread() { -// //TODO: reduce Thread::Thread.numberThread -// if (this->threadName != NULL) { -// free(this->threadName); -// } -//} -// -///** -// * Call Runnable target's run() method -// */ -//void Thread::run() const { -// if (this->target != NULL) { -// this->target->run(); -// } -//} -// -///** -// * Force thread and call Runnable target's run() method -// */ -//void Thread::start() { -// this->isThreadRunning = true; -// pthread_create(&this->original, NULL, &Thread::pthread_helper, (void *) this); -//} -// -///** -// * Stop a thread if it's running -// */ -//void Thread::stop() { -// if (!this->isThreadRunning) { -// return; -// } -// -// //pthread_cancel(this->original); -// this->isThreadRunning = false; -//} -// -///** -// * Waits for this thread to die if it's running -// */ -//void Thread::join() { -// if (!this->isThreadRunning) { -// return; -// } -// -// pthread_join(this->original, NULL); -//} -// -///** -// * Waits at most millis milliseconds for this thread to die if it's running -// */ -//void Thread::join(unsigned int millis) { -// if (!this->isThreadRunning) { -// return; -// } -// -// usleep(millis * 1000); -// pthread_join(this->original, NULL); -//} -// -///** -// * Return this thread's name -// */ -//string Thread::getName() { -// return this->threadName; -//} -// -///** -// * Set this thread's name -// */ -//void Thread::setName(string target) { -// this->threadName = stringCopy(target); -//} -// -///** -// * Returns a string representation of this thread, including the thread's name, priority, and thread group. -// */ -//string Thread::toString() const { -// return this->threadName; -//} +using namespace std; +using namespace Java::Lang; + +thread_local Thread* currentThreadPtr = NULL; + +Thread::Thread() { + init(nullptr, ""); +} + +Thread::Thread(Runnable *target) { + init(target, ""); +} + +Thread::Thread(std::function func) { + this->func = func; +} + +Thread::~Thread() { + if (threadObject.joinable()) + threadObject.join(); + if (semaphoreObject.availablePermits() > 0) + semaphoreObject.release(semaphoreObject.availablePermits()); +} + +void Thread::run() { + // set thread id + this->tid = (unsigned long)pthread_self(); + + // set tls + if (currentThreadPtr == NULL) { + currentThreadPtr = this; + } + + mutexObject.lock(); + alive = true; + mutexObject.unlock(); + + if (this->func) { + this->func(); + } + semaphoreObject.release(1); + + mutexObject.lock(); + alive = false; + mutexObject.unlock(); +} + +void Thread::setName(String name) { + this->name = name; +} + +void Thread::init(Runnable *target, String name) { + this->target = target; + this->name = name; + this->func = std::bind(&Runnable::run, target); +} + +String Thread::getName() { + return this->name; +} + +boolean Thread::isAlive() { + std::unique_lock locker(mutexObject); + return alive; +} + +unsigned long Thread::getId() { + return this->tid; +} + +void Thread::start() { + if (this->func && !isAlive()) { + threadObject = std::move(std::thread(&Thread::run, this)); + } +} + +void Thread::join() { + join(0); +} + +void Thread::join(long millis) { + if (millis > 0) { + semaphoreObject.tryAcquire(1, millis); + } else { + semaphoreObject.acquire(); + } +} + +void Thread::detach() { + if (this->detached) { + throw IllegalArgumentException("Detached thread"); + } else { + this->threadObject.detach(); + this->detached = true; + } +} void Thread::sleep(long millis) { - long currentTime = System::currentTimeMillis(); - while (true) { - if (System::currentTimeMillis() - currentTime > millis) { - break; - } - } -} \ No newline at end of file + this_thread::sleep_for(chrono::milliseconds(millis)); +} + +Thread *Thread::currentThread() { + return currentThreadPtr; +} diff --git a/library/Java/Lang/Thread/Thread.hpp b/library/Java/Lang/Thread/Thread.hpp index 0529b644..86cc8964 100755 --- a/library/Java/Lang/Thread/Thread.hpp +++ b/library/Java/Lang/Thread/Thread.hpp @@ -27,68 +27,87 @@ #ifndef NATIVE_JAVA_LANG_THREAD_HPP #define NATIVE_JAVA_LANG_THREAD_HPP -#include +#include #include "../Object/Object.hpp" -#include "../String/String.hpp" #include "../Runnable/Runnable.hpp" -#include "../System/System.hpp" +#include "../../Util/Concurrent/Semaphore/Semaphore.hpp" -namespace Java { - namespace Lang { - class Thread : public Object, public virtual Runnable { - private: - pthread_t original; - string threadName; - Runnable *target; - - boolean isThreadRunning; - ///Adds-on function to adapt pthread_create of C style - public: - void *pthread_run(void *context) { - ((Thread *) context)->target->run(); - } - - static void *pthread_helper(void *context) { - return ((Thread *) context)->pthread_run(context); - } - - public: - Thread(); - - Thread(Runnable &target2); - - Thread(Runnable &target2, String name); - - Thread(String name); - - //Thread(ThreadGroup group, Runnable &target); - //Thread(ThreadGroup group, Runnable &target, String &name); - //Thread(ThreadGroup group, Runnable &target, String &name, long stackSize); - //Thread(ThreadGroup group, String &name); - ~Thread(); - - public: - void run() const; - - void start(); +using namespace Java::Util::Concurrent; - void stop(); - - void join(); - - void join(unsigned int millis); - - string getName(); - - static void sleep(long millis); - - static void sleep(long millis, int nanos); - - void setName(string target); - - String toString() const; - }; - } -} - -#endif // JAVA_LANG_THREAD_THREAD_HPP \ No newline at end of file +namespace Java { + namespace Lang { + class Thread : public Object, public virtual Runnable { + private: + boolean alive = false; + boolean detached = false; + String name; + unsigned long tid = 0; + Runnable *target = NULL; + Semaphore semaphoreObject; + std::thread threadObject; + std::mutex mutexObject; + std::function func; + + private: + /** + * Initializes a Thread. + * + * @param target the object whose run() method gets called + * @param name the name of the new Thread + * @param stackSize the desired stack size for the new thread, or + * zero to indicate that this parameter is to be ignored. + */ + void init(Runnable *target, String name); + + public: + Thread(); + Thread(Runnable* target); + Thread(std::function func); + ~Thread(); + + void run() override; + + /** + * Changes the name of this thread to be equal to the argument + * name. + * + * First the checkAccess method of this thread is called + * with no arguments. This may result in throwing a + * SecurityException. + * + * @param name the new name for this thread. + * @exception SecurityException if the current thread cannot modify this + * thread. + * @see #getName + * @see #checkAccess() + */ + void setName(String name); + + /** + * Returns this thread's name. + * + * @return this thread's name. + * @see #setName(String) + */ + String getName(); + + boolean isAlive(); + + unsigned long getId(); + + void start(); + + void join(); + + void join(long millis); + + void detach(); + + static void sleep(long millis); + + static Thread* currentThread(); + }; + } // namespace Lang +} // namespace Java + +#endif // JAVA_LANG_THREAD_THREAD_HPP_ \ No newline at end of file diff --git a/library/Java/Lang/Thread/ThreadTest.cpp b/library/Java/Lang/Thread/ThreadTest.cpp index b1e29b15..34d87cc7 100755 --- a/library/Java/Lang/Thread/ThreadTest.cpp +++ b/library/Java/Lang/Thread/ThreadTest.cpp @@ -26,9 +26,188 @@ #include "../../../../kernel/Test.hpp" #include "Thread.hpp" +#include "../InterruptedException/InterruptedException.hpp" +using namespace std; using namespace Java::Lang; +class RunnableTarget1 : public virtual Runnable { +public: + long value; + + RunnableTarget1() { + value = 0; + } + + ~RunnableTarget1() { + + } + + void run() override { + value = 0xb00b; + Thread::sleep(1000); + } +}; + +class RunnableTarget2 : public virtual Runnable { +public: + long value; + + RunnableTarget2() { + value = 0; + } + + ~RunnableTarget2() { + + } + + void run() override { + value = 0xb00b; + Thread::sleep(1000); + value = 0xbeef; + } +}; + +class RunnableTarget3 : public virtual Runnable { +public: + unsigned long tid; + + RunnableTarget3() { + + } + + ~RunnableTarget3() { + + } + + void run() override { + tid = (unsigned long)pthread_self(); + } +}; + +int runnableFuncValue = 0; +void runnableFunc() { + runnableFuncValue = 0xb00b; + Thread::sleep(100); +} + TEST (JavaLangThread, Sleep) { - Thread::sleep(1); + Thread::sleep(1); +} + +TEST(JavaLangThread, ThreadRun) { + { + long expect = 0xb00b; + long result = 0; + RunnableTarget1* target = new RunnableTarget1(); + + Thread thread(target); + thread.start(); + thread.join(); + result = target->value; + + delete target; + assertEquals(expect, result); + } + + { + long expect = 0xb00b; + long result = 0; + + Thread thread(runnableFunc); + thread.start(); + thread.join(); + result = runnableFuncValue; + + assertEquals(expect, result); + } + + { + long expect = 0xb00b; + long result = 0; + + Thread thread([&result](){ + result = 0xb00b; + }); + thread.start(); + thread.join(); + + assertEquals(expect, result); + } + +} + +TEST(JavaLangThread, ThreadSetName) { + Thread thread; + + String name = "Thread 1"; + thread.setName(name); + assertEquals("Thread 1", thread.getName().toString()); + + thread.setName("Thread 2"); + assertEquals("Thread 2", thread.getName().toString()); +} + +TEST(JavaLangThread, ThreadGetName) { + Thread thread; + + String name = "Thread 1"; + thread.setName(name); + assertEquals("Thread 1", thread.getName().toString()); + + thread.setName("Thread 2"); + assertEquals("Thread 2", thread.getName().toString()); +} + +TEST(JavaLangThread, ThreadGetThreadId) { + RunnableTarget3 target; + Thread thread(&target); + + thread.start(); + thread.join(); + + String expect = String::format("%lld", target.tid); + String result = String::format("%lld", thread.getId()); + + assertEquals(expect.toString(), result.toString()); +} + +TEST(JavaLangThread, ThreadJoinWithTimeout) { + long expect1 = 0xb00b; + long result1 = 0; + long expect2 = 0xbeef; + long result2 = 0; + + { + RunnableTarget2 target; + Thread thread(&target); + thread.start(); + + // + thread.join(100); + result1 = target.value; + + // + thread.join(); + result2 = target.value; + } + + assertEquals(expect1, result1); + assertEquals(expect2, result2); +} + +TEST(JavaLangThread, ThreadDetach) { + { + Thread thread([](){ + Thread::sleep(100); + }); + + try { + thread.start(); + thread.detach(); + thread.join(); + } catch (IllegalArgumentException &e) { + assertEquals("Detached thread", e.getMessage()); + } + } } \ No newline at end of file diff --git a/library/Java/Util/Concurrent/Semaphore/Semaphore.cpp b/library/Java/Util/Concurrent/Semaphore/Semaphore.cpp index 21731265..7a89828c 100644 --- a/library/Java/Util/Concurrent/Semaphore/Semaphore.cpp +++ b/library/Java/Util/Concurrent/Semaphore/Semaphore.cpp @@ -25,8 +25,10 @@ */ #include "Semaphore.hpp" +#include "../../../Lang/IllegalArgumentException/IllegalArgumentException.hpp" using namespace std::chrono; +using namespace Java::Util; Concurrent::Semaphore::Semaphore() { permitCounter = 0; @@ -135,3 +137,4 @@ boolean Concurrent::Semaphore::tryAcquire(int permits, long timeout) { } } } + diff --git a/library/Java/Util/Concurrent/Semaphore/Semaphore.hpp b/library/Java/Util/Concurrent/Semaphore/Semaphore.hpp index 1fcc5446..f35e0f13 100644 --- a/library/Java/Util/Concurrent/Semaphore/Semaphore.hpp +++ b/library/Java/Util/Concurrent/Semaphore/Semaphore.hpp @@ -27,8 +27,8 @@ #ifndef NATIVE_JAVA_UTIL_CONCURRENT_SEMAPHORE_SEMAPHORE_HPP #define NATIVE_JAVA_UTIL_CONCURRENT_SEMAPHORE_SEMAPHORE_HPP -#include "../../../Lang.hpp" -#include "../../../Lang/IllegalArgumentException/IllegalArgumentException.hpp" +#include "../../../Lang/String/String.hpp" +#include "../../../Lang/Object/Object.hpp" #include #include