Skip to content
This repository has been archived by the owner on Dec 5, 2022. It is now read-only.

Azy : [Windows] Multiple HTTP queries failing will make ecore to enter an infinite error loop #1

Open
gfriloux opened this issue Apr 7, 2017 · 1 comment
Labels

Comments

@gfriloux
Copy link
Owner

gfriloux commented Apr 7, 2017

If you try to query a webserver that is turned off, youll get a connection refused.
If you do that often enough, you will end up with having ecore's mainloop to continuously call MsgWaitForMultipleObjects(), with the latter always returning an error, and GetLastError() returning 87 (Invalid parameters).

It will endlessly print the following error message :
ERR:ecore ecore_main.c:2047 _ecore_main_win32_select() ( 87) Paramtre incorrect.

And the main loop wont let anything else happend.

Using ecore_con_url in the same context doesnt trigger any probleme, so it is unsure that the bug rely inside ecore, it might only be a consequence of whats being done inside azy.

@gfriloux gfriloux added the bug label Apr 7, 2017
@gfriloux
Copy link
Owner Author

gfriloux commented Apr 7, 2017

The following example code triggers the bug :

/* i686-w64-mingw32-gcc -o query.exe query.c `pkg-config --libs --cflags azy eina ecore` */
#include <Eina.h>
#include <Ecore.h>
#include <Azy.h>

typedef struct _Query
{
   Azy_Client *cli;

   struct
   {
      Ecore_Event_Handler *connected,
                          *disconnected,
                          *transfer_progress;
   } ev;
} Query;

void query_free(Query *q);

Eina_Bool
query_event_transfer_progress(
   void    *data,
   int      type EINA_UNUSED,
   void    *ev)
{
   Query                              *q   = data;
   Azy_Event_Client_Transfer_Progress *dse = ev;
   size_t                              size;
   char                               *s;
   int                                 len;

   if (q->cli != dse->client)
     return EINA_TRUE;

   EINA_LOG_DBG("Receiving data");
   azy_client_close(dse->client);
   return EINA_TRUE;
}

Eina_Bool
query_event_disconnected(
   void    *data,
   int      type EINA_UNUSED,
   void    *ev)
{
   Query      *q      = data;
   Azy_Client *client = ev;

   if (q->cli != client)
     return EINA_TRUE;

   EINA_LOG_DBG("q[%p] client[%p]", q, client);

   query_free(q);
   return EINA_TRUE;
}

Eina_Bool
query_event_connected(
   void    *data,
   int      type EINA_UNUSED,
   void    *ev)
{
   Query        *q   = data;
   Azy_Client   *cli = ev;
   Azy_Net      *net;

   if (q->cli != cli)
      return EINA_TRUE;

   EINA_LOG_DBG("q[%p] client[%p]", q, cli);
   net = azy_client_net_get(cli);
   EINA_SAFETY_ON_NULL_GOTO(net, free_query);

   azy_net_protocol_set(net, AZY_NET_PROTOCOL_HTTP_1_0);
   azy_net_uri_set(net, "/");
   azy_client_blank(cli, AZY_NET_TYPE_POST, NULL, NULL, NULL);
   return EINA_TRUE;

free_query:
   query_free(q);
}

void
query_free(
   Query *q)
{
   if (q->ev.transfer_progress) ecore_event_handler_del(q->ev.transfer_progress);
   if (q->ev.disconnected)      ecore_event_handler_del(q->ev.disconnected);
   if (q->ev.connected)         ecore_event_handler_del(q->ev.connected);

   azy_client_free(q->cli);
   free(q);
}

Eina_Bool
_query_new(void *data)
{
   Query *q;
   Eina_Bool r;

   q = calloc(1, sizeof(Query));
   EINA_SAFETY_ON_NULL_RETURN_VAL(q, EINA_TRUE);

#define _EV(_a, _b, _c, _d)                                                    \
   _a = ecore_event_handler_add(AZY_EVENT_CLIENT_ ## _b, query_event_ ## _c, _d)

   _EV(q->ev.connected, CONNECTED, connected, q);
   EINA_SAFETY_ON_NULL_GOTO(q->ev.connected, free_q);

   _EV(q->ev.disconnected, DISCONNECTED, disconnected, q);
   EINA_SAFETY_ON_NULL_GOTO(q->ev.disconnected, free_q);

   _EV(q->ev.transfer_progress, TRANSFER_PROGRESS, transfer_progress, q);
   EINA_SAFETY_ON_NULL_GOTO(q->ev.transfer_progress, free_q);
#undef _EV

   q->cli = azy_client_new();
   EINA_SAFETY_ON_NULL_GOTO(q->cli, free_q);

   r = azy_client_host_set(q->cli, "192.168.4.110", 4333);
   EINA_SAFETY_ON_TRUE_GOTO(!r, free_q);

   r = azy_client_connect(q->cli);
   EINA_SAFETY_ON_TRUE_GOTO(!r, free_q);

   azy_client_timeout_set(q->cli, 10);
   return EINA_TRUE;

free_q:
   query_free(q);
   return EINA_TRUE;
}




int main(int argc, char **argv)
{
   azy_init();

   ecore_timer_add(1, _query_new, NULL);

   ecore_main_loop_begin();

   azy_shutdown();
   return 0;
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

1 participant