$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 "../../include/ecl/ipc/semaphore.hpp" 00018 #include "../../include/ecl/ipc/shared_memory.hpp" 00019 00020 #ifdef ECL_HAS_SEMAPHORES 00021 00022 /***************************************************************************** 00023 ** Using 00024 *****************************************************************************/ 00025 00026 using std::string; 00027 using ecl::SharedMemory; 00028 using ecl::Semaphore; 00029 using ecl::Sleep; 00030 00031 /***************************************************************************** 00032 ** Doxygen 00033 *****************************************************************************/ 00034 00039 /***************************************************************************** 00040 ** Namespaces 00041 *****************************************************************************/ 00042 00043 namespace ecl { 00044 namespace ipc { 00045 namespace tests { 00046 00047 /***************************************************************************** 00048 ** Data Storage Class 00049 *****************************************************************************/ 00050 00051 class SemaphoreTestData { 00052 public: 00053 double value[2]; 00054 void initialise() { value[0] = 1.0; value[1] = 2.0; }; 00055 }; 00056 00057 } // namespace tests 00058 } // namespace ipc 00059 } // namespace ecl 00060 00061 /***************************************************************************** 00062 ** Using 00063 *****************************************************************************/ 00064 00065 using ecl::ipc::tests::SemaphoreTestData; 00066 00067 /***************************************************************************** 00068 ** Doxygen 00069 *****************************************************************************/ 00070 00075 /***************************************************************************** 00076 ** Tests 00077 *****************************************************************************/ 00078 00079 TEST(SemaphoreTests,access) { 00080 00081 string sm_name("shared_memory"); 00082 string sem_name("shared_semaphore"); 00083 Sleep sleep; 00084 00085 pid_t pID = fork(); 00086 if (pID == 0) 00087 { 00088 /********************************************************************* 00089 ** Child 00090 *********************************************************************/ 00091 sleep(1); 00092 try { 00093 SharedMemory<SemaphoreTestData> sm(sm_name); 00094 Semaphore semaphore(sem_name); 00095 // std::cout << "Child waiting" << std::endl; 00096 // std::cout << "Child trying the lock" << std::endl; 00097 if ( !semaphore.trylock() ) { 00098 // std::cout << "Child tried the lock but failed, now hard locking" << std::endl; 00099 semaphore.lock(); 00100 } 00101 // std::cout << "Child entering shared memory" << std::endl; 00102 SemaphoreTestData *data = sm.data(); 00103 // std::cout << "Child: " << data->value[0] << " " << data->value[1] << std::endl; 00104 EXPECT_EQ(1.3,data->value[0]); 00105 EXPECT_EQ(2.3,data->value[1]); 00106 semaphore.unlock(); 00107 } catch ( ecl::StandardException &e) { 00108 // Don't fail the test, hudson doesn't let us have permissions for instance. 00109 std::cout << e.what() << std::endl; 00110 } 00111 } 00112 else if (pID < 0) // failed to fork 00113 { 00114 std::cerr << "Failed to fork" << std::endl; 00115 exit(1); 00116 } 00117 else 00118 { 00119 /********************************************************************* 00120 ** Parent 00121 *********************************************************************/ 00122 try { 00123 SharedMemory<SemaphoreTestData> sm(sm_name); 00124 Semaphore semaphore(sem_name); 00125 SemaphoreTestData *data = sm.data(); 00126 semaphore.lock(); 00127 // std::cout << "Parent in the shared memory" << std::endl; 00128 sleep(2); 00129 data->value[0] = 1.3; 00130 data->value[1] = 2.3; 00131 EXPECT_EQ(1.3,data->value[0]); 00132 EXPECT_EQ(2.3,data->value[1]); 00133 // std::cout << "Parent: " << data->value[0] << " " << data->value[1] << std::endl; 00134 // std::cout << "Parent leaving shared memory" << std::endl; 00135 semaphore.unlock(); 00136 sleep(3); 00137 } catch ( ecl::StandardException &e) { 00138 // Don't fail the test, hudson doesn't let us have permissions for instance. 00139 std::cout << e.what() << std::endl; 00140 } 00141 } 00142 SUCCEED(); 00143 00144 } 00145 00146 /***************************************************************************** 00147 ** Main program 00148 *****************************************************************************/ 00149 00150 int main(int argc, char **argv) { 00151 00152 std::cout << std::endl; 00153 std::cout << "What you should see:" << std::endl; 00154 std::cout << " - Process forks" << std::endl; 00155 std::cout << " - Parent creates shared memory." << std::endl; 00156 std::cout << " - Parent locks a semaphore and enters shared memory for 2 seconds." << std::endl; 00157 std::cout << " - Child waits one second and attempts to lock the already locked semaphore." << std::endl; 00158 std::cout << " - Parent writes into shared memory and unlocks the semaphore." << std::endl; 00159 std::cout << " - Child finally gains access and reads the shared memory." << std::endl; 00160 std::cout << " - Parent process sleeps for four seconds while child dies." << std::endl; 00161 std::cout << " - Parent dies." << std::endl; 00162 std::cout << std::endl; 00163 00164 testing::InitGoogleTest(&argc,argv); 00165 return RUN_ALL_TESTS(); 00166 } 00167 00168 #else 00169 00170 /***************************************************************************** 00171 ** Alternative Main 00172 *****************************************************************************/ 00173 00174 int main(int argc, char **argv) { 00175 std::cout << std::endl; 00176 std::cout << "Semaphores are not supported on this platform (or ecl is just lacking)." << std::endl; 00177 std::cout << std::endl; 00178 return 0; 00179 } 00180 00181 #endif /* ECL_HAS_SEMAPHORES */ 00182 00183