{"action":"created","issue":{"url":"https://api.github.com/repos/libevent/libevent/issues/258","labels_url":"https://api.github.com/repos/libevent/libevent/issues/258/labels{/name}","comments_url":"https://api.github.com/repos/libevent/libevent/issues/258/comments","events_url":"https://api.github.com/repos/libevent/libevent/issues/258/events","html_url":"https://github.com/libevent/libevent/issues/258","id":89575541,"number":258,"title":"evhttp_connection_cb_cleanup \"event_assign called on an already added event\" ","user":{"login":"gj12","id":8588565,"avatar_url":"https://avatars.githubusercontent.com/u/8588565?v=3","gravatar_id":"","url":"https://api.github.com/users/gj12","html_url":"https://github.com/gj12","followers_url":"https://api.github.com/users/gj12/followers","following_url":"https://api.github.com/users/gj12/following{/other_user}","gists_url":"https://api.github.com/users/gj12/gists{/gist_id}","starred_url":"https://api.github.com/users/gj12/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gj12/subscriptions","organizations_url":"https://api.github.com/users/gj12/orgs","repos_url":"https://api.github.com/users/gj12/repos","events_url":"https://api.github.com/users/gj12/events{/privacy}","received_events_url":"https://api.github.com/users/gj12/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-06-19T14:17:09Z","updated_at":"2015-07-10T06:10:01Z","closed_at":null,"body":"I get the error: \r\n```\r\n[err] event_assign called on an already added event 0x72ba50 (events: 0x0, fd: -1, flags: 0x81)\r\n```\r\nin this scenario:\r\n1. event_base_loop(base,EVLOOP_NO_EXIT_ON_EMPTY);  running in another pthread.\r\n2. evhttp connection retries set to >=2\r\n3. add 100 requests to a not established evhttp_connection \r\n4. the target http server must be offline/not reachable\r\n\r\nReproducible with the following modifications to sample/https-client.c \r\n(start https-client with  -url http://127.0.0.1 -retries 2)\r\n\r\n```diff\r\n--- old.c       2015-06-19 15:50:58.635678158 +0200\r\n+++ https-client.c      2015-06-19 15:48:23.085672893 +0200\r\n@@ -38,6 +38,7 @@\r\n #include <event2/listener.h>\r\n #include <event2/util.h>\r\n #include <event2/http.h>\r\n+#include <event2/thread.h>\r\n\r\n #include <openssl/ssl.h>\r\n #include <openssl/err.h>\r\n@@ -45,9 +46,18 @@\r\n\r\n #include \"openssl_hostname_validation.h\"\r\n\r\n+#include <pthread.h>\r\n+#include <unistd.h>\r\n+\r\n static struct event_base *base;\r\n static int ignore_cert = 0;\r\n\r\n+static void*\r\n+evbase_thread(void* p)\r\n+{\r\n+       event_base_loop(base,EVLOOP_NO_EXIT_ON_EMPTY);\r\n+}\r\n+\r\n static void\r\n http_request_done(struct evhttp_request *req, void *ctx)\r\n {\r\n@@ -204,7 +214,11 @@\r\n        struct evhttp_request *req;\r\n        struct evkeyvalq *output_headers;\r\n        struct evbuffer * output_buffer;\r\n-\r\n+       pthread_t thr;\r\n+\r\n+       event_enable_debug_mode();\r\n+       evthread_use_pthreads();\r\n+\r\n        int i;\r\n\r\n        for (i = 1; i < argc; i++) {\r\n@@ -347,6 +361,8 @@\r\n                return 1;\r\n        }\r\n\r\n+       pthread_create(&thr, NULL, evbase_thread, NULL);\r\n+\r\n        // Create OpenSSL bufferevent and stack evhttp on top of it\r\n        ssl = SSL_new(ssl_ctx);\r\n        if (ssl == NULL) {\r\n@@ -359,7 +375,7 @@\r\n        #endif\r\n\r\n        if (strcasecmp(scheme, \"http\") == 0) {\r\n-               bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);\r\n+               bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE|BEV_OPT_THREADSAFE);\r\n        } else {\r\n                bev = bufferevent_openssl_socket_new(base, -1, ssl,\r\n                        BUFFEREVENT_SSL_CONNECTING,\r\n@@ -384,8 +400,11 @@\r\n\r\n        if (retries > 0) {\r\n                evhttp_connection_set_retries(evcon, retries);\r\n+\r\n        }\r\n-\r\n+\r\n+       for(i = 0; i < 100;++i)\r\n+       {\r\n        // Fire off the request\r\n        req = evhttp_request_new(http_request_done, bev);\r\n        if (req == NULL) {\r\n@@ -425,7 +444,11 @@\r\n                fprintf(stderr, \"evhttp_make_request() failed\\n\");\r\n                return 1;\r\n        }\r\n-\r\n+       }\r\n+\r\n+       for(;;)\r\n+               sleep(1);\r\n+\r\n        event_base_dispatch(base);\r\n\r\n        evhttp_connection_free(evcon);\r\n```"},"comment":{"url":"https://api.github.com/repos/libevent/libevent/issues/comments/120242261","html_url":"https://github.com/libevent/libevent/issues/258#issuecomment-120242261","issue_url":"https://api.github.com/repos/libevent/libevent/issues/258","id":120242261,"user":{"login":"gj12","id":8588565,"avatar_url":"https://avatars.githubusercontent.com/u/8588565?v=3","gravatar_id":"","url":"https://api.github.com/users/gj12","html_url":"https://github.com/gj12","followers_url":"https://api.github.com/users/gj12/followers","following_url":"https://api.github.com/users/gj12/following{/other_user}","gists_url":"https://api.github.com/users/gj12/gists{/gist_id}","starred_url":"https://api.github.com/users/gj12/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gj12/subscriptions","organizations_url":"https://api.github.com/users/gj12/orgs","repos_url":"https://api.github.com/users/gj12/repos","events_url":"https://api.github.com/users/gj12/events{/privacy}","received_events_url":"https://api.github.com/users/gj12/received_events","type":"User","site_admin":false},"created_at":"2015-07-10T06:10:01Z","updated_at":"2015-07-10T06:10:01Z","body":"Normaly we don't have this problem, because the evhttp_error_cb calls evhttp_connection_free .evhttp_connection_free does the event_del(&evcon->retry_ev);. \r\nhttps://github.com/libevent/libevent/pull/175 moves evhttp_connection_reset_ before the evtimer_assign block. This causes the \"double add\". Calling evhttp_connection_free here would clean all pending requests. I just put the event_del(&evcon->retry_ev) stuff from evhttp_connection_free in  evhttp_connection_reset_ to clean the retry_ev. Another way is to clean the retry_ev in `evhttp_error_cb: case EVCON_CONNECTING:`\r\n"}}