2009-05-14 7 views
1

Je travaille sur un programme qui est essentiellement monothread, et son seul thread est le thread principal de boucle d'événements. Par conséquent, toutes ses structures de données ne sont fondamentalement pas protégées par quelque chose comme une région critique. Les choses fonctionnent bien jusqu'à ce qu'il intègre récemment de nouvelles fonctions basées sur l'API DirectShow. Certaines API DirectShow ouvrent une seconde boucle d'événements et, dans cette seconde boucle, elles envoient des messages (c'est-à-dire appellent d'autres appels de gestion d'événement de façon imprévisible). Ainsi, lorsqu'une deuxième fonction de gestion d'événement est invoquée, elle risque d'endommager la structure de données à laquelle accède la fonction qui appelle l'API DirectShow.Comment faire face à une deuxième boucle d'événements avec message-dispatch?

J'ai de l'expérience en programmation de noyau. Et ce qui me vient à l'esprit, c'est que, pour un programme monothread, la façon dont il devrait gérer sa structure de données est très similaire à celle que le noyau devrait avoir avec la structure de données par CPU. Et dans le noyau, lorsqu'une fonction accède à des données par CPU, elle doit désactiver l'interruption (tout comme la distribution des messages dans une seconde boucle d'événements). Cependant, je trouve qu'il n'y a aucun moyen facile d'éviter d'invoquer l'API DirectShow ou d'empêcher la création d'une seconde boucle d'événements à l'intérieur d'eux, y a-t-il un moyen?

+0

Je trouve difficile de comprendre ce que vous demandez. Voulez-vous empêcher DirectShow de déclencher des événements, voulez-vous empêcher DirectShow de pomper des messages ou souhaitez-vous garantir un accès synchrone à vos données? Si vous voulez simplement ignorer les événements de DirectShow, essayez de vérifier le paramètre Sender avant de faire quoi que ce soit dans votre gestionnaire. – dss539

+0

Son problème est la ré-entrée. Sa boucle de message principal reçoit un message et appelle un gestionnaire d'événement pour le gérer. Le gestionnaire commence la mise à jour d'une structure de données et, avant la fin, appelle une fonction API. En interne, la fonction API entre dans une boucle modale. Il distribue ensuite un message, rentrant dans son WindProc. Son code appelle alors un gestionnaire pour le message, qui met à jour la même structure de données, la corrompant. –

+0

Les boucles modales explicites ne sont pas le seul problème. Même quelque chose d'aussi inoffensif que UpdateWindow peut entraîner le traitement d'un message WM_MOUSEACTIVATE. https://bugzilla.mozilla.org/show_bug.cgi?id=490461#c11 – Neil

Répondre

0

Il existe plusieurs solutions possibles qui viennent à l'esprit, selon exactement ce qui se passe mal et votre code:

  1. Assurez-vous que vos structures de données sont dans un état cohérent avant d'appeler toutes les API qui exécutent une boucle modale.
  2. Si cela n'est pas possible, vous pouvez utiliser une simple variable booléenne pour protéger la structure. Si c'est le cas, abandonnez simplement toute tentative de mise à jour ou mettez la mise à jour en file d'attente pour plus tard. Une autre option consiste à annuler l'opération précédente.
  3. Si le problème provient d'événements générés par l'utilisateur, désactivez les menus ou les boutons problématiques pendant que l'opération est en cours. Vous pouvez également afficher une boîte de dialogue modale.
1

mutex. sémaphores. verrouillage. quel que soit le nom que vous voulez l'appeler, c'est ce dont vous avez besoin.

+0

Pas une bonne réponse. –

+0

Mutex, sémaphores, verrouillage sont pour multi-threading. Ma situation n'est pas un problème multi-threading mais plutôt un problème de ré-entrée. – Middleware

Questions connexes