[c++]mutexen

Pagina: 1
Acties:

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 01-02 09:13
Ik heb een DLL gemaakt, die een plugin voor een simulatie programma is.
Het simulatie programma gebruikt de volgende methode: (in chronologische volgorde)

- Initialize()
- InitializeRun()
- myFunction()
- TerminateRun()
- Terminate()

myFunction wordt elke simulatie stap aangeroepen.
De DLL maakt gemaakt van een shared memory object die met een mutex beheerd wordt. De mutex wordt alsvolgt aangemaakt:
C++:
1
2
TCHAR szNameMutex[]=TEXT("Mutex_name");
HANDLE hMutex = CreateMutex(NULL,FALSE,szNameMutex);


Nu wordt by InitializeRun de mutex gepakt (omdat tijdens de simulatie het shared memory aangepast wordt) mbt: (de mutex wordt correct gepakt en komt in de case WAIT_OBJECT_0)
C++:
1
2
3
4
5
6
7
8
9
10
11
DWORD dwWaitResult;                                                                  // Request ownership of mutex.
     dwWaitResult = WaitForSingleObject(hMutex,1000L);                                    // 1 second time-out interval
     switch (dwWaitResult){
          case WAIT_OBJECT_0:
          // Wat inits voor simulatie, mutex wordt NIET vrijgegeven
               return 1;  // return 1=gelukt, 0=niet gelukt
          case WAIT_TIMEOUT:
               return 0;
          case WAIT_ABANDONED:
               return 0;
     }


Dan bij TerminateRun()
C++:
1
2
      
ReleaseMutex(hMutex);

Deze geeft een 0 terug, oftewel er iets niet goed gegaan.
Het blijkt dat ik de mutex gewoon weer kan pakken met de code zoals bij InitializeRun staat.

Mijn vraag is nu hoe het komt dat ie al vrijgegeven is, of gaat dat vanzelf als een methode afgesloten wordt. En hoe kan ik dit voorkomen. Ik wil de code niet in de simulatie stap zetten ivm snelheid.

Tevens doe de andere applicatie (die ook het shared memory kan wijzigen) helemaal niets. De fout zit hem dus echt in deze code.

if broken it is, fix it you should


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13-02 14:38
Als ReleaseMutex 1 retourneert, is het juist wél goed gegaan. ;)

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 01-02 09:13
Soultaker schreef op maandag 18 september 2006 @ 19:47:
Als ReleaseMutex 1 retourneert, is het juist wél goed gegaan. ;)
idd, hij geeft een nul terug; ik hoop dat ie een één terug geeft ;)

if broken it is, fix it you should


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13-02 14:38
(Dat stond er net anders niet. :P)

Is dit nog allemaal binnen één proces? Want zonder security attributes kan 'ie alleen binnen het proces gebruikt worden.

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 01-02 09:13
Soultaker schreef op maandag 18 september 2006 @ 20:39:
(Dat stond er net anders niet. :P)

Is dit nog allemaal binnen één proces? Want zonder security attributes kan 'ie alleen binnen het proces gebruikt worden.
offtopic:
nee, dat klopt, typo ;)


Dit is idd binnen één proces (de DLL), echter wordt de mutex door het andere programma ook gebruikt en wordt op dezelfde manier geopend. Maar dit proces doet momenteel niets.

Verder:
The handle returned by CreateMutex has the MUTEX_ALL_ACCESS access right; it can be used in any function that requires a handle to a mutex object, provided that the caller has been granted access. If a mutex is created from a service or a thread that is impersonating a different user, you can either apply a security descriptor to the mutex when you create it, or change the default security descriptor for the creating process by changing its default DACL. For more information, see Synchronization Object Security and Access Rights.
bron

All access moet toch goed zijn als ik 2 processen heb?
n.b. Ik gebruik nu maar één proces, het tweede proces wordt geheel niet gebruikt. Alles wordt gedraaid in de volgorde zoals in de TS staat.

Edit: Nu weet ik niet hoe het simulatie programma werkt, het kan best zijn dat deze een tweede proces pakt voor de simulatie zelf (dus dat de init door een ander proces gedaan is). Hoe moet ik dat dan gaan doen met de security attributes?

[ Voor 8% gewijzigd door elgringo op 18-09-2006 20:53 ]

if broken it is, fix it you should


  • MisterData
  • Registratie: September 2001
  • Laatst online: 11-02 08:33
Kijk anders eerst even of dat het geval is door GetCurrentProcess aan te roepen en de PID ergens te outputten ofzo? :)

  • The End
  • Registratie: Maart 2000
  • Laatst online: 17:26

The End

!Beginning

Als de thread niet de owner is van de mutex, dan kan het zijn dat er niet genoeg rechten zijn om de mutex te releasen.

Bij de remarks van ReleaseMutex staat hoe je de owner moet worden van de mutex.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Euh, de ownership van een mutex krijg je juist door erop te wachten (WaitForSingleObject dus) :)
elgringo schreef op maandag 18 september 2006 @ 19:33:
Deze geeft een 0 terug, oftewel er iets niet goed gegaan.
Wat is 'iets'? Wat geeft je GetLastError()?

[ Voor 54% gewijzigd door .oisyn op 19-09-2006 11:07 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 01-02 09:13
MisterData schreef op maandag 18 september 2006 @ 21:38:
Kijk anders eerst even of dat het geval is door GetCurrentProcess aan te roepen en de PID ergens te outputten ofzo? :)
Hoe bedoel je dat? ik kan het pid van de dll wel op gaan vragen bij de initialisatie en elke integratie stap bedoel je?
The End schreef op dinsdag 19 september 2006 @ 11:04:
Als de thread niet de owner is van de mutex, dan kan het zijn dat er niet genoeg rechten zijn om de mutex te releasen.

Bij de remarks van ReleaseMutex staat hoe je de owner moet worden van de mutex.
Kan zijn, maar is niet zo, standaard wordt ie gemaakt met MUTEX_ALL_ACCESS dus moet het gewoon werken.

Als ik in temrinaterun ReleaseMutex aanroep en dan getlasterror doe krijg ik 288 terug.
Dat is: ERROR_NOT_OWNER
288 Attempt to release mutex not owned by caller.

[ Voor 39% gewijzigd door elgringo op 19-09-2006 11:28 ]

if broken it is, fix it you should


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Kom, een beetje meer moeite doen hoor :/
In de MSDN, ga naar GetLastError, klik op de link System error codes ergens in de tekst, en je vindt:

288 Attempt to release mutex not owned by caller. ERROR_NOT_OWNER
(Met FormatMessage() kun je een errorcode trouwens naar een leesbare string omzetten zodat je die kunt outputten, zoals je in de docs van GetLastError kunt lezen)

Probleem: je releaset een mutex terwijl je nooit een WaitForSingleObject hebt gedaan (of die is mislukt). Moeten we je nou echt zo aan het handje meenemen?

[ Voor 25% gewijzigd door .oisyn op 19-09-2006 11:25 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 01-02 09:13
.oisyn schreef op dinsdag 19 september 2006 @ 11:23:
Kom, een beetje meer moeite doen hoor :/
In de MSDN, ga naar GetLastError, klik op de link System error codes ergens in de tekst, en je vindt:

288 Attempt to release mutex not owned by caller. ERROR_NOT_OWNER
(Met FormatMessage() kun je een errorcode trouwens naar een leesbare string omzetten zodat je die kunt outputten, zoals je in de docs van GetLastError kunt lezen)

Probleem: je releaset een mutex terwijl je nooit een WaitForSingleObject hebt gedaan (of die is mislukt). Moeten we je nou echt zo aan het handje meenemen?
Dat is idd het probleem, ja. De vraag is nu waarom ik de handelingen zoals in de ts heb gedaan in eendezelfde dll WaitForSingleObject en Releasemutex heb gedaan en het niet werkt.
Als ik heb relase in de initializemethode zelf werkt ie wel.

En dan komt mij vraag weer:
Mijn vraag is nu hoe het komt dat ie al vrijgegeven is, of gaat dat vanzelf als een methode afgesloten wordt. En hoe kan ik dit voorkomen.

Edit:
@misterdata: GetCurrentProcess geeft bij initialze en de simulatiestap FFFFFFFF terug

[ Voor 4% gewijzigd door elgringo op 19-09-2006 11:40 ]

if broken it is, fix it you should


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Natuurlijk wordt een mutex niet gereleased op het moment dat je uit een methode gaat, hoe weet Windows nou dat dat gebeurt? Ik zou gewoon een simpele wrapper class maken die die mutex wrapt, zodat je een countertje kunt bijhouden als je een wait (counter++) en een release (counter--) doet. Vervolgens plaats je in die wait en release methods van je class breakpoints, en dan kun je precies zien wanneer erop gewacht wordt en wanneer hij vrijgegeven wordt.

Als die release een error geeft terwijl de counter niet 0 is (na de decrement) weet je dat iemand anders nog iets met die mutex doet - wellicht dat andere proces dat ook iets met de mutex doet

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 01-02 09:13
Als initialize de eerste keer (eerste simulatie) aangeroepen is komt waitforsingleobject bij:
WAIT_ABANDONED
0x00000080L The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
If the mutex was protecting persistent state information, you should check it for consistency.
uit. Dit zou dus moeten betekenen dat een thread de mutex wel gepakt heeft maar niet vrijgegeven toen de thread beeindigt is. Als ik de simulatie stop worden ReleaseMutex(hMutex) en CloseHandle(hMutex) één keer aangeorpen. Het enige proces wat een handle naar de mutex heeft in mijn tweede proces, maar ide doet er niets mee (pakt hem niet oid).
Hoe komt het dat ie dan toch een WAIT_ABANDONED krijgt? Of heeft het er idd mee te maken dat een tweede proces ook nog een handle heeft.

Edit: die releasemutex geeft dus een error omday ie niet gepakt is en bij de init een WAIT_ABANDONED kreeg. De tweede keer (dat ie daadwerkelijk wel gepakt werd) werkte het wel.

[ Voor 8% gewijzigd door elgringo op 19-09-2006 11:55 ]

if broken it is, fix it you should


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13-02 14:38
Ik zou de invocatie van al je functies eens printen, met proces en thread identifiers, want wat er precies gebeurt is absoluut niet te volgen, en dat is nu juist essentieel om uit te vinden wat er mis gaat. Volgens het verhaal in je TS is er maar één proces met één thread, maar dat is duidelijk niet het geval.

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 01-02 09:13
Soultaker schreef op dinsdag 19 september 2006 @ 15:21:
Ik zou de invocatie van al je functies eens printen, met proces en thread identifiers, want wat er precies gebeurt is absoluut niet te volgen, en dat is nu juist essentieel om uit te vinden wat er mis gaat. Volgens het verhaal in je TS is er maar één proces met één thread, maar dat is duidelijk niet het geval.
In de testsituatie wel.

De tweede applicatie/proces doet nu niet. Deze heb ik al nalopen en deze mutexen werken, maar omdat deze niet actief is heeft dit geen invloed.
De simulatie werkte waarschijnlijk met meerdere threads, maar omdat ik de source hiervan niet heb weet ik niet precies wat die allemaal aan het uitvoeren is, ik ben nog in overleg met de makers hiervan

if broken it is, fix it you should


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12-2025
.oisyn schreef op dinsdag 19 september 2006 @ 11:39:
Natuurlijk wordt een mutex niet gereleased op het moment dat je uit een methode gaat, hoe weet Windows nou dat dat gebeurt?
Zo'n gekke vraag is dat niet; het is tenslotte een [c++] mutex vraag. Het probleem is dat de Win32 API geen C++ maar C is. Dus geen destructors, en geen autorelease. Elke C++ mutex class heeft dat wel.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Like duh, kijk naar z'n code. Ik zie geen C++ class, die suggereerde ik zelfs ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 01-02 09:13
Ter aanvulling het zijn een bunch of methoden die aangeroepen worden en niet in een class oid zitten

Edit:
Ik heb de oplossing van de makers:
Het lijkt er op dat je gelijk hebt.
De Terminate en TerminateRun worden vanuit een andere thread aangeroepen als de Initialize en InitializeRun. Ik kan mij niet meer herinneren waarom dit zo is uitgeprogrammeerd, en zal dit waarschijnlijk in de toekomst dan ook veranderen/verbeteren.

Voorlopig kun je een workaround doen door een "finalequations" block op te nemen in je 20-sim model waarin je een functie aan roept in je DLL om het geheugen vrij te geven.

Bedankt voor deze melding!
Dus we gaan gewoon de workaround pakken

[ Voor 74% gewijzigd door elgringo op 19-09-2006 22:09 ]

if broken it is, fix it you should

Pagina: 1