123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- \section{Utilisation d'objets proxy}
- Nous allons alors utiliser les différentes abstractions mises en place
- précédemment pour la communication inter-processus, que ce soit pour le
- transfert de données de contrôle pour les RPC ou des données applicatives avec
- les blocs mémoires. C'est ici qu'intervient le découpage de l'application en
- différents morceaux ainsi que les méthodes synchrones qu'on va utiliser pour
- pouvoir les relier sans altérer le fonctionnement actuel. On va donc également
- devoir définir quels seront les points d'entrées pour la sandbox, c'est-à-dire
- la manière dont la sandbox va pouvoir s'injecter dans le code existant.
- Le pattern utilisé ici sera principalement d'avoir un objet proxy pour tous les
- objets qui seront utilisé entre processus.
- Dans cette partie, nous allons majoritairement prendre en considération le cas
- du découpage du décodeur, ainsi que des objets étant directement lié à son
- fonctionnement.
- % TODO: graphe d'interaction du décodeur
- \section{Intégration des objets proxys dans l'architecture}
- Le décodeur est dans notre cas créé via l'appel à \inltype{input_DecoderNew}. On
- va donc stocker une nouvelle table de fonctions dans la libvlc, dont l'une
- \inltype{pf_create_stage} indiquera comment créer un étage donné. On peut alors
- surcharger \inltype{input_DecoderNew} poour appeler \inltype{pf_create_stage} et
- initialiser cette dernière à des valeurs différentes selon si on démarre en
- sandbox ou non. Cela justifie notamment les pointeurs \inltype{create_vlc} et
- \inltype{delete_vlc} dans la configuration de lancement de la sandbox.
- \begin{code}{c}{Création du décodeur}
- decoder_t *input_DecoderNew( input_thread_t *p_input,
- es_format_t *fmt, input_clock_t *p_clock,
- sout_instance_t *p_sout )
- {
- return vlc_CreateStage( VLC_OBJECT(p_input), STAGE_DECODER,
- p_input, fmt, p_clock, p_sout );
- }
- \end{code}
- Le décodeur fonctionne dans son propre thread et subit des interactions
- principalement depuis l'objet \inltype{input} via l'API de fonctions commençant
- par \inltype{input_Decoder}. On va donc rajouter une table virtuelle dans
- l'objet représentant le décodeur pour pouvoir changer de stratégie lors de sa
- création.
- Ce pattern va être présent pour tous les objets qui sont fonctionnellement liés
- au décodeur. En particulier, on a par exemple l'input et le décodeur proxy dans
- un processus, puis l'input proxy et le décodeur dans un autre, donnant lieu à la
- situation suivante.
- \begin{figure}[htbp]
- \centering
- \includesvg[width = 250pt]{schemas/decoder_proxy}
- \caption{Proxy input et décodeur avec le modèle}
- \end{figure}
- Les paragraphes précédents décrivent la création d'un décodeur depuis le
- processus de l'input, mais on voit au graphe précédent qu'il faut également
- pouvoir faire un proxy de l'input dans le processus du décodeur, c'est-à-dire
- pouvoir «transmettre» l'input d'un processus à l'autre. Nous allons donc
- reprendre le concept de jeton d'accès et permettre l'envoi d'objet proxy à
- travers une IPC.\@ Il faut alors détailler ces objets proxies du point de vue de
- l'envoi de message.
- \begin{code}{c}{Structure privée d'un objet proxy}
- struct vlc_rpc_proxy_t
- {
- vlc_process_interconn_t *interconn;
- uint32_t id;
- uint32_t stage_id;
- void *p_this;
- vlc_rpc_proxy_cb call;
- };
- \end{code}
- Chaque objet proxy dispose de cette structure. \inltype{interconn} indique la
- méthode de communication pour rejoindre l'autre étage dans un autre processus.
- \inltype{stage_id} indique au broker quel processus contacter pour l'envoi.
- Enfin, tous les objets proxies disposent d'un identifiant unique au processus,
- permettant d'envoyer ou recevoir des RPC.\@ En cas de réception, \inltype{call}
- sera appelé.
- \begin{code}{c}{Fonction de rappel pour les proxies}
- typedef void (*vlc_rpc_proxy_cb)(vlc_rpc_proxy_t *p_proxy,
- uint32_t i_query,
- vlc_process_msg_t *p_msg);
- \end{code}
- Comme ces objets seront «transmis», il faut alors seulement définir des méthodes
- pour créer un \inltype{vlc_rpc_proxy_t} depuis un objet existant, et créer un
- objet proxy à partir d'un \inltype{vlc_rpc_proxy_t}.
- \section{Avantages et limites}
- Commençons par des désavantages liées à cette méthode par rapport à la
- précédente. D'abord, bien qu'apportant l'isolation demandée au chapitre
- précédent, elle demande bien plus de travail d'intégration. En plus de cela, on
- voit avec la relation entre l'input et le décodeur que la méthode est beaucoup
- soumise aux défauts ou aux difficultés d'architecture du projet et qu'il devient
- nécessaire d'effectuer des réécritures de certaines parties.
- Un exemple non présenté ici est celui de la réécriture de
- l'\inltype{input_clock} en \inltype{vlc_clock}, pour des raisons différentes
- mais apportant plus de flexibilité pour ce modèle.
- De plus, beaucoup d'abstraction doit être apportée sous la forme de tables
- virtuelles dans les différents objets de VLC.\@ Bien que pouvant apporter de la
- flexibilité, cela demande beaucoup de transfor,ation sur la manière de
- programmer dans l'application en général.
- Enfin, comme expliqué dans le chapitre sur la boucle événementielle, toutes les
- opérations, et en particulier les RPC dans des RPC ne sont pas possibles et
- limmitent particulièrement la conception de ce modèle.
- Néanmoins, ces défauts peuvent être considérés comme des incitations à améliorer
- la conception générale de l'application en donnant une ligne directrice très
- claire.
|