]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
test/multi_stress_watch: use condition_variable for level triggering 36820/head
authorKefu Chai <kchai@redhat.com>
Wed, 26 Aug 2020 09:56:59 +0000 (17:56 +0800)
committerKefu Chai <kchai@redhat.com>
Wed, 26 Aug 2020 11:17:54 +0000 (19:17 +0800)
* use mutex+condition_variable instead of POSIX semaphore, for
  couple reasons:
  - for using POSIX semaphore, we should set the initial value:
    before this change, sem_init() is not called, so the initial
    value of the semaphore is not set.
  - use condition_variable::wait_for() instead of TestAlarm. simpler
    this way. and avoid hiding the magic numbers -- if we choose to
    live with them, make them more visible.
  - use RAII to avoid sem_init() and sem_destroy()
  - use a member variable for being level triggered. as notify()
    could be called before wait() is called.
* define 10000 using a constant variable: NR_ITERATIONS
* remove unused `#include <sstream>` and using declaration.
* use cout for printing informative messages

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/test/multi_stress_watch.cc

index 0871f3380d2832aad1bcc19a9461b5b42bba165a..1c18d917870b9bad674c414a7d2ab308d1db4551 100644 (file)
@@ -3,10 +3,12 @@
 #include "include/rados/librados.hpp"
 #include "test/librados/test_cxx.h"
 
-#include <semaphore.h>
 #include <errno.h>
+
+#include <mutex>
+#include <condition_variable>
+#include <chrono>
 #include <map>
-#include <sstream>
 #include <iostream>
 #include <string>
 #include <stdlib.h>
 
 using namespace librados;
 using std::map;
-using std::ostringstream;
 using std::string;
 
-static sem_t sem;
-
 class WatchNotifyTestCtx : public WatchCtx
 {
 public:
-    void notify(uint8_t opcode, uint64_t ver, bufferlist& bl) override
-    {
-      sem_post(&sem);
-    }
+  WatchNotifyTestCtx(std::mutex &lock)
+    : lock{lock} {}
+  void notify(uint8_t opcode, uint64_t ver, bufferlist &bl) override {
+    std::unique_lock locker {lock};
+    notified = true;
+    cond.notify_one();
+  }
+  bool wait() {
+    std::unique_lock locker {lock};
+    return cond.wait_for(locker, std::chrono::seconds(1200),
+                        [this] { return notified; });
+  }
+
+private:
+  bool notified = false;
+  std::mutex& lock;
+  std::condition_variable cond;
 };
 
 #pragma GCC diagnostic ignored "-Wpragmas"
@@ -50,20 +62,20 @@ test_loop(Rados &cluster, std::string pool_name, std::string obj_name)
     exit(1);
   }
 
-  for (int i = 0; i < 10000; ++i) {
-    std::cerr << "Iteration " << i << std::endl;
+  std::mutex lock;
+  constexpr int NR_ITERATIONS = 10000;
+  for (int i = 0; i < NR_ITERATIONS; ++i) {
+    std::cout << "Iteration " << i << std::endl;
     uint64_t handle;
-    WatchNotifyTestCtx ctx;
+    WatchNotifyTestCtx ctx{lock};
     ret = ioctx.watch(obj_name, 0, &handle, &ctx);
     ceph_assert(!ret);
     bufferlist bl2;
     ret = ioctx.notify(obj_name, 0, bl2);
     ceph_assert(!ret);
-    TestAlarm alarm;
-    sem_wait(&sem);
+    ceph_assert_always(ctx.wait());
     ioctx.unwatch(obj_name, handle);
   }
-
   ioctx.close();
   ret = cluster.pool_delete(pool_name.c_str());
   if (ret < 0) {
@@ -133,8 +145,8 @@ int main(int args, char **argv)
     pool_name = argv[2];
     obj_name = argv[3];
   }
-  std::cerr << "Test type " << type << std::endl;
-  std::cerr << "pool_name, obj_name are " << pool_name << ", " << obj_name << std::endl;
+  std::cout << "Test type " << type << std::endl;
+  std::cout << "pool_name, obj_name are " << pool_name << ", " << obj_name << std::endl;
 
   if (type != "ec" && type != "rep") {
     std::cerr << "Error: " << argv[0] << " Invalid arg must be 'ec' or 'rep' saw " << type << std::endl;
@@ -170,6 +182,5 @@ int main(int args, char **argv)
   else if (type == "ec")
     test_erasure(cluster, pool_name, obj_name);
 
-  sem_destroy(&sem);
   return 0;
 }