sem_wait() zeigt fehlerhaftes Verhalten?



  • Hi,
    ich bin mir nicht ganz sicher ob ich da einen Fehler gemacht habe oder ob ich einen Fehler in den POSIX-Threads (RT-Extension) gefunden habe.
    Ich habe mir eine Event-Klasse gebastelt, die mir das Leben ein wenig einfacher machen soll. Knackpunkt: sem_wait() gibt in manchen Fällen -1 (Invalid Value) zurück. Ein aufruf ohne Ctor findet nicht statt. Ich bin kurz davor die Klasse mit nem Conditional Mutex zu implimentieren.

    Event.cpp (mit bissl Debug-Code, wie man ihn nicht gestalten sollte *g*)

    #include <errno.h>
    #include <unistd.h>
    #include "OEPlatformEvent.h"
    
    #ifndef errno
    	extern int errno;
    #endif
    
    namespace OE
    {
    	namespace Platform
    	{
    		Event::Event(bool initialState, const char* name)
    		{
    			switch (sem_init(&event_, 0, initialState ? 1 : 0))
    			{
    				case 0:
    					break;
    
    				case EINVAL:
    					throw "Value exceeds SEM_VALUE_MAX";
    
    				case ENOSYS:
    					throw "Sharing Events between processes is not allowed";
    			}
    		}
    
    		Event::~Event()
    		{
    			sem_destroy(&event_);
    		}
    
    		void Event::set()
    		{
    			std::cout << "+" << (void*)&event_ << "|SET" <<  std::endl;
    			if (sem_post(&event_) != 0)
    				throw "Setting Event failed";
    		}
    
    		void Event::reset()
    		{
    			while (sem_trywait(&event_) == 0);
    		}
    
    		bool Event::wait(unsigned int waitTime)
    		{
    			if (waitTime != OE_INFINITE)
    			{
    				for (unsigned int i = waitTime; i != 0; --i)
    				{
    					if (tryWait())
    						return true;
    
    					usleep(1000);
    				}
    			}
    			else
    			{
    
    				int v = 0;
    				sem_getvalue(&event_, &v);
    				std::cout << "+" << (void*)&event_ << "|" << v << std::endl;
    
    				int status =  sem_wait(&event_);
    				if (status == -1)
    				{
    					std::cout << "|" << (void*)&event_ << "|" << errno << strerror(errno) << std::endl;
    				}
    				std::cout << "-" << (void*)&event_ << "|" << v << std::endl;
    				return true;
    
    			}
    
    			return false;
    		}
    
    		bool Event::tryWait()
    		{
    			return sem_trywait(&event_) == 0;
    		}
    	}
    }
    

    Ausgabe:

    ... kleiner Regressiontest für das Event ...

    :EventThread Waiting for event...

    +0x80a32a4|0

    :Thread Test Setting event

    +0x80a32a4|SET
    -0x80a32a4|0

    :EventThread ...done!
    :EventThread TryWait should fail
    :Thread Test TryWait should fail
    :Thread Test Waiting for event...

    +0x80a32a4|0

    :EventThread Setting event

    +0x80a32a4|SET
    -0x80a32a4|0

    :Thread Test ...done!
    :Thread Test TryWait should fail
    :Thread Test Waiting for EventThread

    ... andere Stelle im Programm ...

    +0x80a033a|0
    |0x80a033a|22Invalid argument <-- sem_wait() schlägt fehl, das SET sollte danach aufgerufen werden, aber weil das Event nicht blockt: Segfault.
    -0x80a033a|0

    Ideen?

    Grüße,
    Christoph


Anmelden zum Antworten