This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Concurrency Problem


Hi everybody,

I'm migrating several C++ based programs from Watcom 10.5 to Cygnus 
compiler.

After some steps and hard working I've got the code compiled and 
executed. This is a server software to server in a Client/Server 
structure.When I test it with only a client, it seems to work properly. 
But when I add more than a user I get an access violation.

I've investigating several days what's the origin of the error and don't 
have an answer yet. I've been using Cygnus 1.1.4 at first, and Cygnus 
1.3.2 at last with identical results.

I have a static function, reentrant from different threads:


RETVOID McSessHndlr::SessionHandler(void *arglist)
{
 McSessHndlr *SessHndlr = (McSessHndlr *)arglist;
 int rc;
 long DatSz;

 // Este flag es para manejar excepciones en Windows NT con
 // el Watcom 11.0.  Con otras configuraciones, se maneja como
 // antes.
 if (!SessHndlr->handlingException)
     {

     // Alocamos un objeto para manejar los mensajes.
     SessHndlr->MsgHndlr = GetMsgHndlr(SessHndlr->TipoMsgHndlr);

     // Nos preparamos para excepciones.
     int          ExcptFlg;
          #ifdef __OS2__           McExcptHndlr ExcptHndlr((ERR) 
GenericHandler, 0);
     McExcptHndlr *PExcpt = &ExcptHndlr;
     ExcptFlg = MCSETJUMP(PExcpt);
          #else
          ExcptFlg = 0;
          #endif

     // Si no estamos aqui debido a una excepcion ... (operacion normal)
     if (!ExcptFlg)
         {             // Quedamos en un bucle de recibir petici¢n, 
procesarla, y enviar
         // respuesta.
         while (1)
             {
             // Esperar la recepci¢n de un mensaje en la sesi¢n del 
cliente.
             if (SessHndlr->ReceiveFlg)
                 {
                 rc = SessHndlr->Servicio->Receive(
                                         (unsigned char)SessHndlr->Session,
                                         SessHndlr->MsgHndlr->Buf,
                                         SessHndlr->MsgHndlr->BufSz);
                 }
             else
                 {
                 rc = SessHndlr->Servicio->ReceiveAny(
                                         SessHndlr->MsgHndlr->Buf,
                                         SessHndlr->MsgHndlr->BufSz);
                 }

             // Si no hemos recibido un mensaje, salimos.
             if (rc == -1)
                 {
                 SessHndlr->Session = 0;
                 break;
                 }
             else DatSz = rc;

             // En el caso de ReceiveAny, tenemos que saber de que sesion
             // ha venido el mensaje.
             if (!SessHndlr->ReceiveFlg) SessHndlr->Session = rc;

             // Procesamos el mensaje.  Si no hay respuesta, salimos.
             SessHndlr->MsgHndlr->MessageHandler(DatSz);              
                                <----------------- Here is the problem
             if (!SessHndlr->MsgHndlr->RespSz) break;
                  // Enviar la respuesta al cliente.
             rc = SessHndlr->Servicio->Send((unsigned 
char)SessHndlr->Session,
                                            SessHndlr->MsgHndlr->Buf,
                                            SessHndlr->MsgHndlr->RespSz);
             if (rc) break;

             memset(SessHndlr->MsgHndlr->Buf, 0, 
SessHndlr->MsgHndlr->BufSz);
             }
         }

     // Quitamos el manejador de excepciones.
     #ifdef __OS2__
          ExcptHndlr.RemoveHandler();
          #endif

     }

 // Ahora con Watcom 11.0 en Windows NT, llegamos aqui cuando hay
 // una excepcion.  Llegamos aqui en una segunda llamada a la rutina.

 // Si estamos aqui, se ha cerrado la conexion o hay una excepcion.
 // Llamamos a todos los destuctores.
 delete SessHndlr;
 int ret = 0;
 McExit(0, ret);  // Salimos de este thread.
}

------------------------------------------------------------------------


int McPetHndlr::MessageHandler(long DatSz, McSock *SockIn)
{
 int rc;

 DatSz = DatSz;  // Evitamos warning.

 // Si es el primer mensaje, inicializamos.
 if (FirstTime)
     {
     FirstTime = 0;
     rc = Inicializar(Mcs.CnxHndlr, Buf, SockIn, 0);
     if (rc == 0)
         return (RespSz = 0);
     }

 // Creamos y tratamos la petici¢n.
 McPet Pet(Usuario, Buf, PETBFSZ, SockIn);
 RespSz = Pet.Tratar();

 // Actualizamos la informacion de este usuario.
 Mcs.CnxHndlr->ActualizarInfo(Usuario);

 return (RespSz);            <----------------   Here is the access 
violation.
}

I always get an access violation in this line I've never got using other 
compilers. The last one is Watcom 10.5, but I could talk about VisualAge 
or Borland, too.

Things I'tested:

 - Add a semaphore into the function closing all code except return 
(RespSz). It fails
 - Include McPet destructor into the semaphore. It fails
 - Add the semaphore out of the function. (In SessionHandler). It works 
fine.


I've tested many more things, but before sending or explaining further 
(not easy) , I'd like to know if there's any known difference beetween 
these two compilers, refered to the following subjetcs:

 - Re-entrance
 - Thread management
 - Static functions

I must say that, at the moment, I could solve the situation setting a 
semaphore out of the function, but obviously slowing the response time 
to clients petitions.


Thanks in advance, Ignasi Villagrasa.




--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]