semaphores.cpp
Go to the documentation of this file.
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 


ecl_ipc
Author(s): Daniel Stonier
autogenerated on Sun Oct 5 2014 23:35:45