2015-04-15 1 views
0

Ceci est le code associé, je l'ai raccourci autant que possible, sans exclure la source de l'erreur. DebugLogMsg est un outil d'écriture de fichier journal semblable à printf qui peut être considéré comme ne causant pas l'erreur.FCGX_Accept_r renvoie le succès sans la demande valide

//Some init stuff and smthng 
    while (1) 
    { 
     memset (&requestFcgx, 0, sizeof (requestFcgx)); 
     iRet = FCGX_InitRequest (&requestFcgx, 0, 0); 
     DebugLogMsg ("FCGX_InitRequest() called!!\r\n"); 

     if (iRet != 0) 
     { 
      DebugLogMsg ("FCGX_InitRequest failed, return val:%d!\r\n", iRet); 
      return NULL; 
     } 

     iRet = FCGX_Accept_r (&requestFcgx); 

     if (iRet != 0) 
     { 
      DebugLogMsg1 ("FCGX_Accept_r failed!\r\n"); 
      continue; 
     } 

     char *foo = FCGX_GetParam("SOME_CUSTOM_VAL", requestFcgx.envp); 
     DebugLogMsg ("CustomParam:%s\r\n", foo); 

     do 
     { 
      //processing the request... 
      if (ERROR == TRUE) 
      { 
       DebugLogMsg ("FatalError!\r\n"); 
       return NULL; 
      } 

      DebugLogMsg ("no errors occured!"); 
     } 
     while (0); 

     FCGX_Finish_r (&requestFcgx); 
     DebugLogMsg ("Cleanup.... DONE!\r\n"); 
    } 

Mon problème est iRet = FCGX_Accept_r (&requestFcgx); ne bloque pas tous les 2ème appel, comme il se doit. (Au moins, je m'attends à ce que cette fonction soit bloquante)

Dès qu'une requête est envoyée par le serveur web, les libérations de fonctions, parcourent la boucle sans aucune erreur, se connectent, appellent le Finish, boucles au début de la corps de la boucle et lors de l'appel à nouveau iRet = FCGX_Accept_r (&requestFcgx);, il retourne instantanément avec iRet == 0 mais la structure requestFcgx semble être invalide (ce qui est à prévoir car il n'y avait même pas une demande supplémentaire initiée). Le fichier journal correspondant contient pour ce processus:

[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] FCGX_InitRequest() called! 
      ---------------------------------------- 
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] CustomParam:ExpectedStuff 
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] no errors occured! 
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] Cleanup.... DONE! 

[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] FCGX_InitRequest() called! 
      ---------------------------------------- 
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] CustomParam:(null) 
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] FatalError! 

////////////////////////////// 
////////Protocol closed/////// 
////////////////////////////// 

(S'il vous plaît quelqu'un modifier le LogText à ne pas formated code, je ne sais pas comment)

L'erreur fatale a lieu comme la demande n » t fournir des informations et se fermer. le point est, pourquoi iRet = FCGX_Accept_r (&requestFcgx); revient avec 0 quand il a obvieriously échoué? Et dans quelle mesure dois-je considérer ce comportement, si on s'attend à le faire.

Répondre

1

Il y a deux questions -

  1. FCGX_InitRequest(&requestFcgx, 0, 0) doit être appelée avant d'entrer dans la boucle while(1).
  2. Le signal SIGPIPE peut également provoquer ce comportement. Essayez de l'ignorer. Ajouter ce bloc au début de votre fonction main() -

    struct sigaction sa_ign; 
    sa_ign.sa_handler = SIG_IGN; 
    sa_ign.sa_flags = 0; 
    sigemptyset(&sa_ign.sa_mask); 
    sigaction(SIGPIPE, &sa_ign, NULL); 
    

Vous avez mentionné que l'application est multi-thread. Si oui, vous devez également appeler le FCGX_Init(). Ci-dessous les informations du fichier fcgiapp.h d'en-tête -

/* 
*---------------------------------------------------------------------- 
* 
* FCGX_Init -- 
* 
*  Initialize the FCGX library. Call in multi-threaded apps 
*  before calling FCGX_Accept_r(). 
* 
*  Returns 0 upon success. 
* 
*---------------------------------------------------------------------- 
*/ 
DLLAPI int FCGX_Init(void); 

Cocher cette application simple FastCGI multi-thread -

http://www.fastcgi.com/devkit/examples/threaded.c

+0

donc 'FCGX_InitRequest (& requestFcgx, 0, 0)' est pas la contre-partie 'FCGX_Finish_r (& requestFcgx)'? Donc 'FCGX_Finish_r (& requestFcgx)' ne nettoie rien, cela doit être réinitialisé? – dhein

+0

Il est bon de savoir, mais malheureusement n'a pas résolu le problème. Est-il important de savoir que 'while (1)' est exécuté dans plusieurs pthreads? J'ai mis le code devant mon 'main()' comme vous l'avez dit. – dhein

+0

FCXG_Finish_r() libère les ressources allouées par FCGX_Accept_r() et doit être appelée à la fin de la boucle While (1) ou avant l'instruction "continue". – Harmeet