ithewei před 5 roky
rodič
revize
26033d761d
5 změnil soubory, kde provedl 47 přidání a 0 odebrání
  1. 1 0
      Makefile
  2. 15 0
      base/hmutex.h
  3. 2 0
      docs/apis.md
  4. 5 0
      unittest/CMakeLists.txt
  5. 24 0
      unittest/synchronized_test.cpp

+ 1 - 0
Makefile

@@ -99,6 +99,7 @@ unittest: prepare
 	$(CC)  -g -Wall -std=c99   -I. -Ibase            -o bin/connect_test      unittest/connect_test.c       base/hsocket.c base/htime.c
 	$(CC)  -g -Wall -std=c99   -I. -Ibase            -o bin/socketpair_test   unittest/socketpair_test.c    base/hsocket.c
 	$(CXX) -g -Wall -std=c++11 -I. -Ibase            -o bin/defer_test        unittest/defer_test.cpp
+	$(CXX) -g -Wall -std=c++11 -I. -Ibase            -o bin/synchronized_test unittest/synchronized_test.cpp -pthread
 	$(CXX) -g -Wall -std=c++11 -I. -Ibase            -o bin/hstring_test      unittest/hstring_test.cpp     base/hstring.cpp
 	$(CXX) -g -Wall -std=c++11 -I. -Ibase            -o bin/threadpool_test   unittest/threadpool_test.cpp  -pthread
 	$(CXX) -g -Wall -std=c++11 -I. -Ibase            -o bin/objectpool_test   unittest/objectpool_test.cpp  -pthread

+ 15 - 0
base/hmutex.h

@@ -224,12 +224,27 @@ public:
 
     void wrlock()   { hrwlock_wrlock(&_rwlock); }
     void wrunlock() { hrwlock_wrunlock(&_rwlock); }
+
+    void lock()     { rdlock(); }
+    void unlock()   { rdunlock(); }
 protected:
     hrwlock_t   _rwlock;
 };
 
+template<class T>
+class LockGuard {
+public:
+    LockGuard(T& t) : _lock(t) { _lock.lock(); }
+    ~LockGuard() { _lock.unlock(); }
+protected:
+    T& _lock;
+};
+
 END_NAMESPACE_HV
 
+// same as java synchronized(lock) { ... }
+#define synchronized(lock) for (std::lock_guard<std::mutex> _lock_(lock), *p = &_lock_; p != NULL; p = NULL)
+
 #endif // __cplusplus
 
 #endif // HV_MUTEX_H_

+ 2 - 0
docs/apis.md

@@ -184,6 +184,8 @@
 - `hv::MutexLock`
 - `hv::SpinLock`
 - `hv::RWLock`
+- `hv::LockGuard`
+- synchronized
 
 ### hsocket.h
 - INVALID_SOCKET

+ 5 - 0
unittest/CMakeLists.txt

@@ -26,6 +26,10 @@ target_include_directories(socketpair_test PRIVATE .. ../base)
 add_executable(defer_test defer_test.cpp)
 target_include_directories(defer_test PRIVATE .. ../base)
 
+add_executable(synchronized_test synchronized_test.cpp)
+target_include_directories(synchronized_test PRIVATE .. ../base)
+target_link_libraries(synchronized_test -lpthread)
+
 add_executable(hstring_test hstring_test.cpp ../base/hstring.cpp)
 target_include_directories(hstring_test PRIVATE .. ../base)
 
@@ -69,6 +73,7 @@ add_custom_target(unittest DEPENDS
     connect_test
     socketpair_test
     defer_test
+    synchronized_test
     hstring_test
     threadpool_test
     objectpool_test

+ 24 - 0
unittest/synchronized_test.cpp

@@ -0,0 +1,24 @@
+#include "hthread.h"
+#include "hmutex.h"
+
+#define THREAD_NUM 10
+std::mutex g_mutex;
+
+HTHREAD_ROUTINE(test_synchronized) {
+    synchronized(g_mutex) {
+        hv_delay(1000);
+        printf("tid=%ld time=%llus\n", hv_gettid(), (unsigned long long)time(NULL));
+    }
+    return 0;
+}
+
+int main() {
+    hthread_t threads[THREAD_NUM];
+    for (int i = 0; i < THREAD_NUM; ++i) {
+        threads[i] = hthread_create(test_synchronized, NULL);
+    }
+    for (int i = 0; i < THREAD_NUM; ++i) {
+        hthread_join(threads[i]);
+    }
+    return 0;
+}