WaitForSingleObject



  • Hi Leute,

    aktuell bin ich dabei eine Treiber-DLL für eine nicht mehr unterstützte Kamera zu schreiben mit Hilfe von ein paar freien Developement-Headern. Diese wird von einem größeren Prozess geladen.
    Nun hänge ich seit zwei Tagen an einem Problem:

    Befindet sich die Kamera an einem bestimmten USB-Port, funktioniert alles einwandfrei. Sobald ich jedoch einen der anderen (alle USB 2.0) verwende,
    erhalte ich nie den Status WAIT_OBJECT_0 von "WaitForSingleObject". Nur in
    ganz seltenen Fällen (wenn man etwas herumspielt) erhalte ich die Bilddaten.

    Hier wird das Event mit dem Handle erzeugt, das die Aufnahme macht:

    // Create an event to get signaled when a frame was acquired
    	ZeroMemory(&hEv_, sizeof(hEv_));
        hEv_ = CreateEvent(NULL, FALSE, FALSE, NULL);
      	retVal = is_InitEvent(hCamera_, hEv_, IS_SET_EVENT_FRAME);
    	retVal = is_EnableEvent(hCamera_, IS_SET_EVENT_FRAME);
    
    	// Set callback
    	pCallBackThread_->setFrameEvent(hEv_);
    	pCallBackThread_->start()
    

    Der Thread übernimmt das Handle und wartet darauf, dass das Event
    in den signalled-Status gelangt um dann fortsetzen zu können:

    DWORD IDSAcqCallBackThread::threadFunction(Thread*)
    {
    	DWORD lEv = 0;
    	stoppable_ = false;
    
    	do 
    	{
    		lEv = WaitForSingleObject(hFrameEv_, timeout_);
    
    		switch( lEv )
    		{
    			case (WAIT_OBJECT_0 + 0):	
    				{
    					IDSGreyAcqFifo::IDSGREYDATA* pData;
    					pData = pFifo_->oldestStartedAcquire();
    					// Segnala
    					IDSGreyAcqFifo::IDSGREYDATA data = *pData;
    					pFifo_->completeAcquire(data);
    				} break;
    
    			case WAIT_TIMEOUT:
    				{
    				} break;
    		}
    	} while (!stopped());
    
    	stoppable_ = true;
    
    	return 0;
    }
    

    mit

    void setFrameEvent(HANDLE h) { hFrameEv_ = h; }
    

    Jedoch erhalte ich, unabhängig vom Wert des Timeouts, auf 2 von 3en meiner
    USB-Ports NIE den WAIT_OBJECT_0 Status der Funktion. Das komische ist, dass
    ich mit Hilfe der mir offenen Developer-Schnittstellen keinen Port definieren
    muss usw., was logischer Weise bedeuten könnte, dass nur einer die Funktion
    wie gewünscht erledigt.

    Hat irgendwer eine Idee woran das liegen könnte?!



  • Dieser Thread wurde von Moderator/in Arcoth aus dem Forum C++ (auch C++0x und C++11) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich würde das ganze mal auf Verdacht mit einem manual-reset Event probieren.
    Sollte in deinem Fall zwar keinen Unterschied machen, aber ist ja schnell ausprobiert.
    Parameter des CreateEvent Aufrufs ändern und ein ResetEvent in den WAIT_OBJECT_0 Case rein und fertig.

    BTW: In deiner Thread Funktion fehlt Synchronisierung (stoppable_ = true;), und du kannst die Frage "stoppable?" auch einfacher beantworten: ein WaitForSingleObject(threadHandle, 0) sagt dir ob der Thread noch läuft.



  • Liuthasil schrieb:

    // Create an event to get signaled when a frame was acquired
    ZeroMemory(&hEv_, sizeof(hEv_));
    hEv_ = CreateEvent(NULL, FALSE, FALSE, NULL);
    ...
    

    - Einen Handle mit ZeroMemory auf NULL zu setzen ist wohl etwas übertrieben.
    - Der Event hat keinen Namen, was möglicherweise Kollisionen mit bereits existierenden Events verursacht.
    - Der Rückgabewert wird nicht ausgewertet, Fehler schlagen später auf.

    Wo einige Konstante und Vaiable herkommen kann man nur vermuten

    hFrameEv_, WAIT_OBJECT_0, ..

    Da es aber scheinbar unter bestimmten Bedingungen läuft kann man hoffen, das hier das Problem nicht liegt.

    - Gibt es ausser WAIT_OBJECT_0 weitere Messages, die von der Camera ausgelöst werden ?
    - Sollten alle WaitForSingleObject() Aufrufe WAIT_TIMEOUT ergeben passiert gar nichts ?



  • merano schrieb:

    - Der Event hat keinen Namen, was möglicherweise Kollisionen mit bereits existierenden Events verursacht.

    Nein, gerade dadurch dass er keinen Namen hat kann es auch keine Probleme geben.

    merano schrieb:

    Wo einige Konstante und Vaiable herkommen kann man nur vermuten

    hFrameEv_, WAIT_OBJECT_0, ..

    lol
    Du hast noch nie WinAPI programmiert, oder?



  • hustbaer schrieb:

    lol
    Du hast noch nie WinAPI programmiert, oder?

    Du bist der Einzige, der sowas kann 😉



  • Nix versteh.
    Wer schonmal mit WinAPI rumgemacht hat, der hat vermutlich auch schon WaitForSingleObject verwendet.
    Und wer jemals WaitForSingleObject mit dwMilliseconds != INFINITE verwendet hat, der sollte auch WAIT_OBJECT_0 kennen.
    Ich meine halt... das ist jetzt echt kein sagenumwobenes Geheimwissen.

    merano schrieb:

    Du bist der Einzige, der sowas kann 😉

    Da würd ich jetzt eher an Martin Richter denken...



  • hustbaer schrieb:

    Nix versteh.
    Wer schonmal mit WinAPI rumgemacht hat, der hat vermutlich auch schon WaitForSingleObject verwendet.
    Und wer jemals WaitForSingleObject mit dwMilliseconds != INFINITE verwendet hat, der sollte auch WAIT_OBJECT_0 kennen.
    Ich meine halt... das ist jetzt echt kein sagenumwobenes Geheimwissen.

    Ok. erwischt WAIT_OBJECT_0+0 ist natürlich klar, auch wenn mich die 0 irgendwie stört - aber wo ist
    z.B. der Wert für dwMilliseconds ?

    Aktuell steht da nur

    Liuthasil schrieb:

    lEv = WaitForSingleObject(hFrameEv_, timeout_);
    

    Wobei weder hFrameEv_ noch timeout_ explizit da steht.

    "If dwMilliseconds is zero, the function does not enter a wait state ..."

    Das hFrameEv_ == hEv_ ist, wird angenommen.

    Die Reaktion auf Fehlerfall fehlt (auch hier) komplett.



  • merano schrieb:

    aber wo ist
    z.B. der Wert für dwMilliseconds ?

    Der ist eigentlich egal, denn...

    merano schrieb:

    "If dwMilliseconds is zero, the function does not enter a wait state ..."

    Jo "does not enter a wait state" heisst aber nicht dass nicht gecheckt wird ob das Objekt nicht eh schon "signaled" ist.

    WaitForSingleObject prüft immer den Zustand des Objekts, und wenn es signaled ist kommt auch immer zuverlässig WAIT_OBJECT_0 zurück. Auch wenn man dwMilliseconds = 0 übergibt. Weiss ich aus Erfahrung, hab mich schon oft genug erfolgreich darauf verlassen 😉

    merano schrieb:

    Die Reaktion auf Fehlerfall fehlt (auch hier) komplett.

    Ja, richtig.

    Wobei das in dem Fall ziemlich egal ist.
    Ich prüfe bei WaitForSingleObject auch nicht auf WAIT_FAILED . Genau so wenig wie ich in einem C++ Programm jeden Zeiger gegen NULL prüfe bevor ich ihn dereferenziere.

    Und was die CreateEvent Sache angeht: da fehlt auch die Überprüfung, und da gehört sie auch hin. Kann aber auch nicht die Fehlerursache sein, da CreateEvent mit diesen Parametern nur fehlschlägt wenn das OS ganz ernsthaften Speichermangel hat.

    Kann also nicht die Ursache für einen "an einem USB Port geht's, an den anderen nicht" Fehler sein.
    Ich würde hier entweder ein Timing-Problem vermuten, oder irgend einen Defekt (defekte Kamera, defekte Ports, verbuggte Firmware/Treiber, ...).



  • Hallo Leute,

    danke für die vielen Antworten und sorry, dass die Prüfungen noch nicht von mir
    implementiert wurden - das ganze musste erstmal quick & dirty laufen. Ich bin
    auch kein Fan davon.

    Ja, an das Timing-Problem hab ich auch schon gedacht, jedoch kann ich mir nicht
    erklären wo es entstehen sollte.

    Ich werde jetzt erstmal die Überprüfung der Rückgabewerte einbauen und mir das
    Ganze nochmal zu gemüte führen, war leider die letzten Tage unterwegs.

    Den gesamten Code wollte ich nicht posten -> zu lang und zu viele redundante
    Informationen 😉



  • Ich habe jetzt schnell die Überprüfung der Rückgabewerte eingebaut.
    Jedoch brachte mich das keine Schritt weiter, da diese in Ordnung sind.
    Es kommt einfach immer die 258 (Timeout) zurück, egal ob man einen Wert
    setzt oder INFINITE verwendet.

    Noch jemand eine hilfreiche Idee?


Anmelden zum Antworten