IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Sybase Discussion :

[CTLIB] fonction callback asynchrone ?


Sujet :

Sybase

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Points : 127
    Points
    127
    Par défaut [CTLIB] fonction callback asynchrone ?
    Bonjour,

    J'utilise un callback de type ClientMessage dans mon application, afin de détecter si il y a eu une déconnexion. Si c'est le cas, dans la fonction callback, je tente de reconnecter l'application puis j'indique via une variable partagée que la commande sybase qui a échouée suite à la déconnexion peut-être relancée.

    Cependant cela ne fonctionne pas car le callback semble être executé "en parallèle" de la commande sybase, et donc lorsque la variable partagée est testée pour savoir si la commande échouée doit être relancée, le callback n'a pas encore mis à jour cette variable.

    Existe-t-il un moyen de synchroniser les callback, et d'éviter une exécution parallèle au process ?


    Merci d'avance

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Points : 1 828
    Points
    1 828
    Par défaut
    Est-ce qu'il s'agit d'une appli multi-threadée ?

    Je ne suis plus tout-à-fait aussi pointu dans la programmation OpenClient que je l'ai été, mais il me semble qu'on ne peut pas appeler ct_connect() depuis un callback.

    Si mes souvenirs sont bons la technique "approvée" est de mettre un flag dans le callback (ce que tu semble faire) et ensuite tester ce flag en dehors du callback pour recréer la connexion avant de pouvoir relancer la commande qui a planté.

    Michael
    Michael Peppler
    Membre de TeamSybase - www.teamsybase.com

    "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Points : 127
    Points
    127
    Par défaut
    Merci pour cette réponse rapide.

    Non il ne s'agit pas d'une appli multi-thread, cependant en effet je fais appel au ct_connect dans mon callback, en plus du flag. La reconnection se fait bien donc je pense que de ce côté là ça va.

    Je vais tout de même essayer de faire autrement et de me contenter de flaguer dans le callback et de reconnecter en dehors.

    Je vais voir ce que ça donne.

    Merci

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Points : 127
    Points
    127
    Par défaut
    Malheureusement ça ne fonctionne toujours pas.

    Si je détecte une deconnection :
    - Dans le callback je flag une variable static "disconnect" à 1

    - Dans le process qui execute la commande sybase, je check directement après le ct_command, la valeur de "disconnect", mais la variable n'a pas été mise à jour par le callback, cette opération est faite de manière désynchronisé, après...

    C'est plutôt embêtant comme comportement...

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Points : 127
    Points
    127
    Par défaut
    Bon je pense avoir avancé dans mon problème.
    D'après ce que j'ai compris, lors d'une déconnection, la notification par le serveur (et donc l'appel du callback associé) a lieu lors de la prochaine tentative de commande sur le serveur.

    Pour éviter ce comportement, il faut modifier la property CS_ASYNC_NOTIFS et la mettre à true.

    Avec l'aide de cette commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ct_con_props(*connexion, CS_SET, CS_ASYNC_NOTIFS, (CS_VOID*)CS_TRUE, CS_UNUSED, NULL)
    Cependant je ne comprends pas cet appel de ct_con_props provoque un "bus error" et un fichier core chez moi !!
    Voici le code complet de ma fonction de connexion, merci de votre aide !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    int ConnectSybase (CS_CONTEXT **contexte, CS_CONNECTION **connexion, CS_COMMAND **commande,
                       char *user, char *passwd, char *server)
    {
        /* Allocation d'une structure de contexte (pour la version 12.5) */
        if (cs_ctx_alloc (CS_VERSION_125, contexte) != CS_SUCCEED)
            return (ERREUR_SYB_CONTEXTE);
     
        /* Initialisation d'Open Client */
        if (ct_init (*contexte, CS_VERSION_125) != CS_SUCCEED)
            return (ERREUR_SYB_CONTEXTE);          
     
        /* Installation des CallBack */
        ct_callback (*contexte, NULL, CS_SET, CS_CLIENTMSG_CB, (CS_VOID *)ClientMsg_Callback);
        ct_callback (*contexte, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID *)ServMsg_Callback);
     
        /* Connexion au serveur */
        ct_con_alloc(*contexte, connexion);        
        ct_con_props(*connexion, CS_SET, CS_USERNAME, user, CS_NULLTERM, NULL);
        ct_con_props(*connexion, CS_SET, CS_PASSWORD, passwd, CS_NULLTERM, NULL);
        /* properties de la connexion : mode asynchrone */
        if (ct_con_props(*connexion, CS_SET, CS_ASYNC_NOTIFS, (CS_VOID*)CS_TRUE, CS_UNUSED, NULL) != CS_SUCCEED)
        {
        	printf("ct_con_props ASYNCHRONOUS failed\n");
        	fflush(stdout);
        	return ERREUR_SYB_CONNEXION;
        }    
     
        /* Creation de la connexion au serveur */
        if (ct_connect(*connexion, server, CS_NULLTERM) != CS_SUCCEED)
            return(ERREUR_SYB_CONNEXION);
     
        /* Allocation d'une structure de commande pour envoyer des commandes */
        if (ct_cmd_alloc(*connexion, commande) != CS_SUCCEED)
            return(ERREUR_SYB_COMMANDE);
     
        return (OK);
    }

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Points : 127
    Points
    127
    Par défaut
    Ok j'ai trouvé la cause de mon core dump (le CS_TRUE passé dans ct_con_props doit être une adresse sur int).

    Une fois la property CS_ASYNC_NOTIFS mis à true, la déconnection est détectée automatiquement et le callback lancé dans la foulée, c'est pas mal du tout.
    Sauf que cela envoie aussi un signal à mon programme qui se kill tout seul du coup argh ...

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Points : 127
    Points
    127
    Par défaut
    Mon programme se kill car il reçoit un Interrupt System Call (EINTR) de la part de la CTlib...

    Ce n'est pas un signal alors je ne sais pas du tout comment ça se catch...

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Points : 1 828
    Points
    1 828
    Par défaut
    Il doit y avoir un problème entre les notifications asynchrones et le reste de ton programme.

    Idéalement il faudrait construire un programme example (aussi petit que possible) qui illustre le problème - cela permettrait probablement de trouver la bonne façon de coder pour arriver à obtenir le comportement que tu cherche.

    Michael
    Michael Peppler
    Membre de TeamSybase - www.teamsybase.com

    "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Points : 127
    Points
    127
    Par défaut
    Rectification : en effet je me suis trompé mon programme n'est pas killé en fait, il sort de son plein gré car c'est programmé ainsi.

    En fait au moment du EINTR, le programme est en attente de réception d'un message sur une file de message (msgrcv()). Le EINTR provoque la sortie de cette fonction et dans mon programme j'interprète cela comme un erreur grave qui provoque une sortie.

    Voici les lignes de codes où le EINTR intervient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    /* Reception du message */
        etat = msgrcv (Cle_File, &mesg, MESG_TAILLE_MAX, MESG_ANY, MSG_NOERROR);
     
        /* Si le message est mal recu ... */
        if (etat < 0)
        {
        	perror("Recoi_Structure");
            return (ERREUR_MESG_RCV);
        }
    Faudrait-il que je teste la valeur de errno et gérer le cas EINTR ?
    De cette manière ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    /* Reception du message */
        while(TRUE)
        {
            etat = msgrcv (Cle_File, &mesg, MESG_TAILLE_MAX, MESG_ANY, MSG_NOERROR);
     
            /* Si le message est mal recu ... */
           if (etat < 0 && errno != EINTR)
           {
        	    perror("Recoi_Structure");
                return (ERREUR_MESG_RCV);
            }
        }
    Cette méthode ne comporte-t-elle pas des risques ??
    Merci d'avance

Discussions similaires

  1. Fonction callback
    Par saibe dans le forum Linux
    Réponses: 4
    Dernier message: 19/01/2012, 10h41
  2. [debutant] fonction callback
    Par samipate dans le forum Langage
    Réponses: 5
    Dernier message: 09/10/2005, 14h59
  3. problème fonctions callback
    Par youp_db dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 02/10/2005, 14h47
  4. [Débutant] fonction CALLBACK
    Par tlt dans le forum MFC
    Réponses: 2
    Dernier message: 29/10/2004, 16h55
  5. Fonction callback dans une classe
    Par julian_ross dans le forum MFC
    Réponses: 8
    Dernier message: 02/03/2004, 11h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo