ref: refs/heads/master
commit 7cd4de02f2e932429227b5534afff39828f7609f
Author: Michael Andres
Date: Thu Jul 23 13:06:18 2009 +0200
Provide more common and convenient shmem access
---
helper/installHelper.cc | 37 ++++++----------
helper/installHelper.h | 107 +++++++++++++++++++++++++++++++----------------
helper/test.cc | 99 +++++++++++++++----------------------------
3 files changed, 119 insertions(+), 124 deletions(-)
diff --git a/helper/installHelper.cc b/helper/installHelper.cc
index e2fcdb7..955fb6a 100644
--- a/helper/installHelper.cc
+++ b/helper/installHelper.cc
@@ -16,12 +16,10 @@ using std::endl;
namespace cmpizypp
{
- Comm & getshmem()
+ managed_shared_memory & shm()
{
- static shared_memory_object shm( open_only, SHM_NAME, read_write );
- //Map the whole shared memory in this process
- static mapped_region region( shm, read_write );
- return * static_cast(region.get_address());
+ static managed_shared_memory managed_shm( open_only, SHM_NAME );
+ return managed_shm;
}
}
@@ -33,34 +31,27 @@ try {
MIL << "InstallHelper " << getpid() << endl;
- MIL << "Waiting for lock..." << endl;
std::string iFile;
{
- CommAccess c( getshmem() );
- MIL << c->pid << endl;
- if ( c->pid != getpid() )
+ ShmAccess<Comm> comm( shm(), "Comm" );
+ MIL << comm->pid << endl;
+ if ( comm->pid != getpid() )
{
- ERR << "Not my pid: " << c->pid << "(" << getpid() << ")" << endl;
+ ERR << "Not my pid: " << comm->pid << "(" << getpid() << ")" << endl;
return 1;
}
- if ( * c->dataStr )
- iFile = c->dataStr;
+ if ( * comm->dataStr )
+ iFile = comm->dataStr;
}
MIL << "read " << iFile << endl;
std::ifstream infile( iFile.c_str() );
for( iostr::EachLine in( infile ); in; in.next() )
{
- DBG << *in << endl;
+ USR << *in << endl;
}
-
-
-
-
-
-
MIL << "Done" << endl;
///////////////////////////////////////////////////////////////////
@@ -69,8 +60,8 @@ try {
return 0;
}
catch ( const Exception & exp )
-{
- INT << exp << endl << exp.historyAsString();
-}
+{ INT << exp << endl << exp.historyAsString(); throw; }
+catch ( const std::string & exp )
+{ INT << "exception: " << exp << endl; throw; }
catch (...)
-{ INT << "exception" << endl; }
+{ INT << "exception" << endl; throw; }
diff --git a/helper/installHelper.h b/helper/installHelper.h
index 49115c3..c5bb49b 100644
--- a/helper/installHelper.h
+++ b/helper/installHelper.h
@@ -1,31 +1,93 @@
#ifndef INSTALLHELPER_H
#define INSTALLHELPER_H
+#include
#include
-#include
-#include
#include
#include
-#define SHM_NAME "MySharedMemory"
-#define STR_SIZE 256
+#define SHM_NAME "cmpi-zypp-helper"
+#define STR_SIZE 256
#define MAX_ANSWERS 10
namespace cmpizypp
{
+ /**
+ * Base class for lockable shared memory objetcs.
+ */
+ struct ShmData
+ {
+ ShmData()
+ : _lock(1)
+ {}
+ boost::interprocess::interprocess_semaphore _lock;
+ };
+
+ /**
+ * Locked access to shared memory objetcs.
+ * \code
+ * struct Comm {...};
+ * managed_shared_memory managed_shm( create_only, SHM_NAME, 65536 );
+ * Comm * comm = managed_shm.construct<Comm>("Comm")();
+ * try
+ * {
+ * ShmAccess<Comm> comm( managed_shm, "Comm" );
+ * // got exclusive access...
+ * }
+ * catch...
+ * \endcode
+ */
+ template <class Derived>
+ class ShmAccess : private boost::noncopyable
+ {
+ public:
+ /**
+ * Ctor for locked access to a named object.
+ * \throws Exception if named object was not found.
+ * \throws Exception if timeout expired.
+ * \todo Define Exceptions.
+ */
+ ShmAccess( boost::interprocess::managed_shared_memory & managed_shm_r,
+ const char * name_r, time_t timeout = 5 )
+ : _d( managed_shm_r.find<Derived>( name_r ).first )
+ {
+ if ( !_d )
+ throw std::string( "Can't find " ) + name_r;
+ if ( _d && ! _d->_lock.timed_wait( boost::posix_time::from_time_t( ::time(0)+timeout ) ) )
+ throw std::string( "Got no lock" );
+ }
+
+ ~ShmAccess()
+ { release(); }
+
+ public:
+ /** Give up lock and access. */
+ void release()
+ { if ( _d ) { _d->_lock.post(); _d = 0; } }
+
+ public:
+ const Derived * get() const { return _d; }
+ Derived * get() { return _d; }
+ const Derived * operator->() const { return _d; }
+ Derived * operator->() { return _d; }
+ const Derived & operator*() const { return _d; }
+ Derived & operator*() { return _d; }
+ private:
+ Derived * _d;
+ };
+
+
enum Answers
{
A_unknown = 0,
A_yes, A_no, A_cancel, A_abort
};
- struct Comm
+ /**
+ */
+ struct Comm : public ShmData
{
- Comm() : lock(1) {}
-
- boost::interprocess::interprocess_semaphore lock;
-
pid_t pid;
uint16_t status;
uint16_t percent;
@@ -35,32 +97,5 @@ namespace cmpizypp
char questionStr[STR_SIZE];
char dataStr[STR_SIZE];
};
-
- struct CommAccess : private boost::noncopyable
- {
- CommAccess( Comm & c )
- : _c( c )
- {
- if ( ! _c.lock.timed_wait( boost::posix_time::from_time_t( ::time(0)+5 ) ) )
- {
- throw "got no lock";
- }
- }
-
- ~CommAccess()
- {
- _c.lock.post();
- }
-
- const Comm * operator->() const
- { return &_c; }
-
- Comm * operator->()
- { return &_c; }
-
- private:
- Comm & _c;
- };
-
}
#endif
\ No newline at end of file
diff --git a/helper/test.cc b/helper/test.cc
index 16ac9ae..36445d4 100644
--- a/helper/test.cc
+++ b/helper/test.cc
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include
#include
@@ -14,40 +15,24 @@
using namespace zypp;
using namespace zypp::filesystem;
-using namespace cmpizypp;
using namespace boost::interprocess;
+using namespace cmpizypp;
using std::endl;
+void shmDebug()
+{
+ ExternalProgram( "ls -l /dev/shm" ) >> MIL;
+}
+
namespace cmpizypp
{
- Comm & getshmem()
+ managed_shared_memory & shm()
{
- static bool initialized = false;
- if ( ! initialized )
- {
- // Create a shared memory object.
- MIL << "Create shared_memory_object " << SHM_NAME << endl;
- }
static ::mode_t mask = ::umask( 0077 );
- static shared_memory_object shm ( create_only, SHM_NAME, read_write );
- if ( ! initialized )
- {
- ::umask( mask );
- // Set size
- shm.truncate( 1000 );
- }
- // Map the whole shared memory in this process
- static mapped_region region( shm, read_write );
- if ( ! initialized )
- {
- // Write all the memory to '0'
- std::memset( region.get_address(), 0, region.get_size() );
- // Initialize
- new ( region.get_address() ) Comm;
- initialized = true;
- }
- return *static_cast(region.get_address());
+ static managed_shared_memory managed_shm( create_only, SHM_NAME, 65536 );
+ static ::mode_t omask = ::umask( mask );
+ return managed_shm;
}
}
@@ -59,51 +44,37 @@ try {
struct shm_remove
{
- shm_remove() {
- MIL << "Remove shared_memory_object " << SHM_NAME << endl;
- shared_memory_object::remove(SHM_NAME);
- }
- ~shm_remove()
- {
- MIL << "Remove shared_memory_object " << SHM_NAME << endl;
- shared_memory_object::remove(SHM_NAME);
- }
+ shm_remove() { shared_memory_object::remove(SHM_NAME); }
+ ~shm_remove() { shared_memory_object::remove(SHM_NAME); }
} remover;
+ if ( ! shm().construct<Comm>("Comm")() )
+ {
+ throw std::string( "Out of shmem constructing Comm" );
+ }
+
// write task list
std::string path( TmpFile().path().asString() );
std::ofstream o( path.c_str() );
o << "hi" << endl;
o.close();
- pid_t p = 0;
- {
- CommAccess c( getshmem() );
-
- // Launch child process
- p = fork();
- if ( p == 0 )
- {
- execvp( "./installHelper", NULL );
- _exit( 128 );
- }
-
- // parent
- MIL << "installHelper started (" << p << ")" << endl;
- c->pid = p;
- strncpy( c->dataStr, path.c_str(), STR_SIZE );
- }
+ ShmAccess<Comm> comm( shm(), "Comm" ); // blocks the helper
+
+ strncpy( comm->dataStr, path.c_str(), STR_SIZE );
- int ret = 0;
- int status = 0;
- do
+ ExternalProgram helper( "./installHelper" );
+ comm->pid = helper.getpid();
+ comm.release(); // go...
+
+ while ( helper.running() )
{
- MIL << "ping..." << endl;
sleep( 5 );
- ret = waitpid( p, &status, WNOHANG );
+ MIL << "ping..." << endl;
}
- while ( ret == 0 || ( ret == -1 && errno == EINTR ) );
- MIL << "installHelper exited!" << endl;
+
+ if ( helper.close() != 0 )
+ ERR << helper.execError() << endl;
///////////////////////////////////////////////////////////////////
INT << "===[END]============================================" << endl << endl;
@@ -111,10 +82,8 @@ try {
return 0;
}
catch ( const Exception & exp )
-{
- INT << exp << endl << exp.historyAsString();
-}
-catch (const char * i)
-{ INT << "Exception :( " << i << endl; }
+{ INT << exp << endl << exp.historyAsString(); throw; }
+catch ( const std::string & exp )
+{ INT << "exception: " << exp << endl; throw; }
catch (...)
-{ INT << "Exception :(" << endl; }
+{ INT << "exception" << endl; throw; }
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org