$search
00001 00009 /***************************************************************************** 00010 ** Includes 00011 *****************************************************************************/ 00012 00013 #include <iostream> 00014 #include <cstdlib> 00015 #include <gtest/gtest.h> 00016 #include <ecl/time/sleep.hpp> 00017 #include <ecl/time/timestamp.hpp> 00018 #include "../../include/ecl/ipc/semaphore.hpp" 00019 #include "../../include/ecl/ipc/shared_memory.hpp" 00020 00021 #ifdef ECL_HAS_SEMAPHORES 00022 00023 /***************************************************************************** 00024 ** Using 00025 *****************************************************************************/ 00026 00027 using std::string; 00028 using ecl::SharedMemory; 00029 using ecl::Semaphore; 00030 using ecl::Duration; 00031 using ecl::Sleep; 00032 00033 /***************************************************************************** 00034 ** Doxygen 00035 *****************************************************************************/ 00036 00041 /***************************************************************************** 00042 ** Namespaces 00043 *****************************************************************************/ 00044 00045 namespace ecl { 00046 namespace ipc { 00047 namespace tests { 00048 00049 /***************************************************************************** 00050 ** Data Storage Class 00051 *****************************************************************************/ 00052 00053 class SemaphoreTimedData { 00054 public: 00055 double value[2]; 00056 void initialise() { value[0] = 1.0; value[1] = 2.0; }; 00057 }; 00058 00059 } // namespace tests 00060 } // namespace ipc 00061 } // namespace ecl 00062 00063 /***************************************************************************** 00064 ** Using 00065 *****************************************************************************/ 00066 00067 using ecl::ipc::tests::SemaphoreTimedData; 00068 00069 /***************************************************************************** 00070 ** Doxygen 00071 *****************************************************************************/ 00072 00077 /***************************************************************************** 00078 ** Tests 00079 *****************************************************************************/ 00080 00081 TEST(SemaphoreTimedTests,access) { 00082 00083 string sm_name("shared_memory"); 00084 string sem_name("shared_semaphore"); 00085 Sleep sleep; 00086 Duration timeout(0,750000000); 00087 00088 pid_t pID = fork(); 00089 if (pID == 0) 00090 { 00091 /********************************************************************* 00092 ** Child 00093 *********************************************************************/ 00094 // std::cout << "Child waiting" << std::endl; 00095 sleep(1); 00096 try { 00097 SharedMemory<SemaphoreTimedData> sm(sm_name); 00098 Semaphore semaphore(sem_name); 00099 // std::cout << "Child trying the lock for 750ms" << std::endl; 00100 bool result = semaphore.trylock(timeout); 00101 EXPECT_FALSE(result); 00102 if ( result ) { 00103 // std::cout << "Child locked semaphore." << std::endl; 00104 } else { 00105 // std::cout << "Child lock attempt timed out." << std::endl; 00106 // std::cout << "Child trying the lock again for 750ms" << std::endl; 00107 if ( (result = semaphore.trylock(timeout)) ) { 00108 EXPECT_TRUE(result); 00109 // std::cout << "Child locked semaphore." << std::endl; 00110 } else { 00111 // std::cout << "Child lock attempt timed out." << std::endl; 00112 } 00113 } 00114 semaphore.unlock(); 00115 } catch ( ecl::StandardException &e ) { 00116 // Don't fail the test, hudson doesn't let us have permissions for instance. 00117 std::cout << e.what() << std::endl; 00118 } 00119 } 00120 else if (pID < 0) // failed to fork 00121 { 00122 std::cerr << "Failed to fork" << std::endl; 00123 exit(1); 00124 } 00125 else 00126 { 00127 /********************************************************************* 00128 ** Parent 00129 *********************************************************************/ 00130 try { 00131 SharedMemory<SemaphoreTimedData> sm(sm_name); 00132 Semaphore semaphore(sem_name); 00133 SemaphoreTimedData *data = sm.data(); 00134 semaphore.lock(); 00135 data->value[0] = 1.3; 00136 data->value[1] = 2.3; 00137 EXPECT_EQ(1.3,data->value[0]); 00138 EXPECT_EQ(2.3,data->value[1]); 00139 // std::cout << "Parent in the shared memory" << std::endl; 00140 // std::cout << "Parent locking the semaphore." << std::endl; 00141 sleep(2); 00142 // std::cout << "Parent unlocking the semaphore." << std::endl; 00143 semaphore.unlock(); 00144 sleep(2); 00145 } catch ( ecl::StandardException &e ) { 00146 // Don't fail the test, hudson doesn't let us have permissions for instance. 00147 std::cout << e.what() << std::endl; 00148 } 00149 } 00150 } 00151 00152 /***************************************************************************** 00153 ** Main program 00154 *****************************************************************************/ 00155 00156 int main(int argc, char **argv) { 00157 00158 std::cout << std::endl; 00159 std::cout << "What you should see:" << std::endl; 00160 std::cout << " - Process forks" << std::endl; 00161 std::cout << " - Parent creates shared memory." << std::endl; 00162 std::cout << " - Parent locks a semaphore and enters shared memory for 2 seconds." << std::endl; 00163 std::cout << " - Child waits one second and tries lock for 750ms." << std::endl; 00164 std::cout << " - Child fails and again tries lock for 750ms." << std::endl; 00165 std::cout << " - Child succeeds in locking.." << std::endl; 00166 std::cout << std::endl; 00167 00168 testing::InitGoogleTest(&argc,argv); 00169 return RUN_ALL_TESTS(); 00170 } 00171 00172 #else 00173 00174 /***************************************************************************** 00175 ** Alternative Main 00176 *****************************************************************************/ 00177 00178 int main(int argc, char **argv) { 00179 std::cout << std::endl; 00180 std::cout << "Semaphores are not supported on this platform (or ecl is just lacking)." << std::endl; 00181 std::cout << std::endl; 00182 return 0; 00183 } 00184 00185 #endif /* ECL_HAS_SEMAPHORES */ 00186 00187 00188 00189 00190 00191 00192