Frage zu Mutex in MFC



  • Hallo Zusammen,

    ich habe gerade sehr merkwürdige Effekte bei denen ein Mutex oder eine CriticalSection nicht greifen.
    Es handelt sich um ein einfaches MFC Project mit einer COM DLL.
    Diese ruft bei Erhalt einer Netzwerknachricht in dem MFC Code eine Funktion auf.
    Dies geschieht mehrmals und ich will das ein wenig ausbremsen, da es zu schnell ist und ich das Erhaltene zuerst dem Benutzer Zeigen will. (Messagebox)
    Also setze ich einen

    EnterCriticalSection(&xy);
    

    gleich nach dem Aufruf der Funktion um einen weiteren Aufruf warten zu lassen. (Vorher Initialisiere ich die CS natürlich in der OnInit)
    Dannach setze ich einen Soundeffect mit "MessageBeep(-1)".

    Leider, leider kommt nach der ersten Messagebox lauter Soundpings und weitere Boxen.

    Warum geht hier kein Mutex, kein CMutex, keine CriticalSection und keine CCriticalSection ?

    Grüße
    TheNoName


  • Mod

    Witzbold: Es ist doch der selbe Thread!



  • Wenn du damit sagen willst das es derselbe Mutex-Member ist -> OK!

    Aber wie macht man eine Critical Section in demselben Thread?

    bzw. verstehe ich nicht was da passiert, nachdem es "ein" Thread ist, müsste ein Aufruf aus der COM DLL den vorhergehenden Prozess abbrechen.


  • Mod

    CriticalSection/Mutexe blockieren nur unterschiedliche Threads.
    Wenn Dein Thread einen Mutex blockiert und nun der selbe Thread blockieren würde weil er wieder bei dem Mutex vorbeikommt, wer soll denn dann bitte den Mutex freigeben?

    Wenn Du Renetrancy bei einem COM Objekt durch Message-Loops vermeiden willst, dann musst Du das mit einem Message-Filter machen, oder einfach mit einer statischen Variable...



  • Wenn Dein Thread einen Mutex blockiert und nun der selbe Thread blockieren würde weil er wieder bei dem Mutex vorbeikommt, wer soll denn dann bitte den Mutex freigeben?

    Haja, ich habe ein WaitForSingleObject für den Mutex am Anfang des Aufrufes eingebaut. Es wird trotzdem drübergegangen, weil wahrscheinlich der Memberzugriff schon für diesen Thread vergeben ist?

    dann musst Du das mit einem Message-Filter machen,

    Ein Messagefilter ist hier so ein Problem, da ich die GUI mit einer Messagepump am Leben erhalten wollte 😞

    oder einfach mit einer statischen Variable

    Hier müsste ich eine Ticketverwaltung aufziehen, weil wenn der eine fertig ist, dann soll "einer" der anderen folgen, nicht alle gleichzeitig weil sie anhand einer boolschen Variable die Funktion alle gleichzeitig frei sehen.

    Frage zum Messagefilter (hast ja gut erkannt, dass das COM Objekt auf Messages aufbaut):
    Kann man bestimmte Messages für bestimmte Zeit zurückstellen, auch wenn ich mit einer Messagepump arbeite?
    Wie sähe der aus?


  • Mod

    Du hast Message-Filter falsch verstanden. Das hat gar nichts mit den UI Messages zu tun sondern mit COM und dem IMessageFilter Interface.
    Dieses wird in in der MFC in COleMessageFilter implementiert!

    COM Reentrancy ist kein trviales Problem, das wirst Du nicht mit Hausmitteln wie Criticalsection oder anderem beheben. Das ist ein Design-Problem der COm Komponente!



  • Aua, ich verstehe meine Verwechslung nun allzu deutlich.
    Da werde ich neu drauf aufsetzen.

    Macht es Sinn bei jedem Comm Aufruf einen Thread zu starten und diesem die COMM Argumente zu übergeben, dort greifen dann ja die CriticalSections wieder?


  • Mod

    Genauso Unfug. Denn was macht dann Deine Applikation.

    Beachte: Deine COM Applikation wird nur reentrant, wenn Du eine UI startest oder selber wierder fremde COM Module aufrufst.



  • Habs jetzt über einen Puffer gelöst, alle COM Parameter werden gesichert und später über einen Timer abgearbeitet.
    Dadurch ist der COM Aufruf so kurz wie möglich.

    Mich hätte jedoch interressiert, ob man das Messagesystem der COM Schnittstelle pausieren kann ohne die komplette COM Netzwerkschnittstelle zu pausieren?
    Dabei müsste die COM eine Art Messagebuffer haben ...


  • Mod

    Über den IMessageFilter kann man detailiert angeben, was mit erneuten Calls passieren soll. Wann ein Retry erfolgt, wann evtl. ein Timeout erfolgt etc.

    Da muss nichts gepuffert werden. COM Aufrufe sind immer synchron!


Anmelden zum Antworten