unlink() + bind() versenyhelyzet UNIX domain socket-re bind-eléskor

Fórumok

Kedves Fórumozók!

A saját fejelsztésű szerverrmhez jelenleg TCP-n lehet kapcsolódni. Ehhez a szerverben a socket(), setsockot(... SO_REUSEADDR) bind(), listen() és accept() függvényeket hívom a megfelelő paraméterekkel. Ha két példányban indítom a szervert, akkor a második példányban a bind() meghiúsul Address already in use-zal. Csodás.

Szeretném a szervert átírni UNIX domain socket-es kapcsolatok fogadására. Ehhez a bind() elé egy unlink()-et kell tenni, azért, mert korábbról a fájlrendszerben ottmaradhatott egy socket fájl, és ha ott marad, akkor a bind() meghiúsul Address already in use-zal, noha nem kéne neki (ugyanis a programnak nem fut második példánya). Tehát a hívási sorrend ez lesz: socket(), setsockopt(... SO_REUSEADDR), unlink(), bind(), listen() és accept() lesz. Na, ezzel az a baj, hogy ekkor el lehet indítani két példányban a szervert, ami rossz.

Tudtok versenyhelyzet (race condition) -mentes megoldást, ami csak egy példányban engedi elindulni a szervert (tehát ha indításkor 0 példány fut, akkor el engedi indulni, ha 1 példány fut, akkor nem engedi, több példány pedig nem futhat), és akkor is működik, ha ott marad egy régi socket fájl?

Google-lel próbáltam "UNIX domain socket" bind "race condition"-re keresni, de nem találtam a specifikációnak megfelelő megoldást. (Amiket találtam, azok vagy nem unlink()-elnek, ami rossz, vagy saját bevallásuk szerint is race conditiön-ösek, ami rossz, vagy egyszerre több példányt is engednek indítani a szerverből, ami rossz).

Kösz:

pts

Hozzászólások

Lama dolog tudom, de tfh az indulo daemon ha talal socketet, bekuld egy 'helo'-t ra (ezt te nyilvan lekezeled, hogy ilyenkor mi tortenjen), ha nem jon ra valasz, akkor a socket halott --> lehet indulni. Ha jott, akkor 'already in use'. De ha jol sejtem ottragadt sockethez valo kapcsolodaskor te mar connrefusedet fogsz kapni.

Az általad javasolt megoldás azért nem jó, mert versenyhelyzet van benne. Ha egyszerre két új szervert akarok indítani, akkor mindkettő úgy érzékelheti, hogy halott a szolgáltatás, mindkettő letörli a socketet, és mindkettő elindul. Pedig alapvető igény, hogy egyszerre maximum 1 szerver futhasson.