Gestion des échecs mq_open après mq_unlink

J’écris un processus client / serveur sur Suse Linux en utilisant des files de messages Posix pour communiquer, similaire à la réponse acceptée dans ” Comment utiliser mqueue dans un programme ac sur un système Linux? “. Lorsque le serveur meurt, il effectue un mq_close et un mq_unlink . Toutefois, le client ne reçoit aucune notification à ce sujet. Par conséquent, les appels à mq_send dans le client continueront à fonctionner même si la queue n’a pas été liée.

Le problème est que, lorsque le serveur est redémarré, il essaie de créer une queue avec mq_open avec O_CREAT, mais cela échoue car le client a toujours un fd ouvert. Ainsi, même si le nom de fichier dans / dev / mqueue ne semble pas exister, le serveur ne peut pas en créer un jusqu’à ce que le client ferme et ferme son descripteur de fichier. Je voulais juste m’assurer de bien comprendre le problème: si je voulais que le serveur ferme, dissocie et réouvre la queue (par exemple, avec des atsortingbuts différents), le client a-t-il vraiment besoin de quitter ou de fermer, c’est fd? Ceci est très différent de la façon dont cela fonctionne avec un fichier brut: je peux supprimer un fichier utilisé par un autre processus, et le système de fichiers peut le renommer “.nfsXXX” et continuer à l’utiliser, mais je peux en créer un nouveau. fichier avec ce nom tout de suite.

Mon premier essai de correction consiste simplement à ne pas dissocier la mqueue lorsque le serveur se ferme – si je veux autoriser le redémarrage du serveur sans que le client doive être redémarré, je suppose que je ne devrais pas dissocier la file (car le serveur sait que le client utilise peut-être encore la queue (mqueue, elle ne devrait pas être non liée).

Ce que j’aimerais idéalement, c’est que le nouveau mq_open réussisse sur le serveur et que le prochain mq_send échoue sur le client. Existe-t-il un moyen simple de simuler cela? Les moyens qui me viennent à l’esprit sont:

  • Faire un fstat (ou quelque chose) sur “/ dev / mqueue / queueName” avant chaque mq_send ( beurk !) Et fermer le fd si le nom n’existe pas (pendant que le serveur essaie de le recréer dans une boucle), ne fonctionne pas parfaitement si le client est actuellement bloqué sur mq_send car la queue était pleine.
  • avoir un socket séparé dans le client auquel le serveur enverrait un message lorsqu’il souhaitait que le (s) client (s) ferme (nt) leurs files d’attente (et probablement un thread séparé dans le client pour surveiller ce socket).
  • demandez au serveur de tuer le ou les clients.