{"action":"created","issue":{"url":"https://api.github.com/repos/warmcat/libwebsockets/issues/235","labels_url":"https://api.github.com/repos/warmcat/libwebsockets/issues/235/labels{/name}","comments_url":"https://api.github.com/repos/warmcat/libwebsockets/issues/235/comments","events_url":"https://api.github.com/repos/warmcat/libwebsockets/issues/235/events","html_url":"https://github.com/warmcat/libwebsockets/issues/235","id":55653603,"number":235,"title":"cpu > 96%","user":{"login":"gmmota","id":10728528,"avatar_url":"https://avatars.githubusercontent.com/u/10728528?v=3","gravatar_id":"","url":"https://api.github.com/users/gmmota","html_url":"https://github.com/gmmota","followers_url":"https://api.github.com/users/gmmota/followers","following_url":"https://api.github.com/users/gmmota/following{/other_user}","gists_url":"https://api.github.com/users/gmmota/gists{/gist_id}","starred_url":"https://api.github.com/users/gmmota/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gmmota/subscriptions","organizations_url":"https://api.github.com/users/gmmota/orgs","repos_url":"https://api.github.com/users/gmmota/repos","events_url":"https://api.github.com/users/gmmota/events{/privacy}","received_events_url":"https://api.github.com/users/gmmota/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-01-27T18:12:47Z","updated_at":"2015-01-28T13:15:35Z","closed_at":null,"body":"\r\nFirst thanks for the library.\r\nI noticed that after a call libwebsocket_cancel_service in another thread, the CPU rises above 96%.\r\nI tested also calling libwebsocket_callback_on_writable_all_protocol that same thread, showing the same thing.\r\nThis thread is simply by setting one flag (ws_flags_write_all) for the main thread calls libwebsocket_callback_on_writable_all_protocol.\r\nThe problem presents itself when enters 'y' via keyboard on which sets the flag and calls libwebsocket_cancel_service.\r\nIn this thread I can get around this by setting the flag and just never calling libwebsocket_cancel_service or libwebsocket_callback_on_writable_all_protocol,\r\nusing a small timeout in libwebsocket_service.\r\nIt is curious because libwebsocket_cancel_service just write the dummy pipe while libwebsocket_callback_on_writable_all_protocol do more things.\r\n\r\nI'm running on the raspberry pi model b.\r\n\r\n## My Thread:\r\n```c\r\nstatic volatile int ws_flags_write_all = 0;\r\n \r\nstatic void * my_thread(void *arg){\r\n    char buf[25];\r\n \r\n    while(!force_exit) {\r\n \r\n        printf(\"\\n>>>\");\r\n        fflush(stdout);\r\n \r\n        if(fgets(buf, 20, stdin)==NULL)\r\n            continue;\r\n                   \r\n        if(buf[0] == 'q' || buf[0] == 'Q'){\r\n            force_exit = 1;\r\n            libwebsocket_cancel_service(context);\r\n            break;\r\n        }\r\n \r\n        switch(buf[0]){\r\n            case 'x': ws_flags_write_all = 1; break;  /* continue dumb protocol, cpu OK  */\r\n            case 'X': ws_flags_write_all = 0; break;  /* pause dumb protocol, cpu OK     */\r\n            case 'y':\t                              /* pause dumb protocol cpu > 96% !!!! */\r\n                ws_flags_write_all = 1;\r\n                libwebsocket_cancel_service(context);\r\n        }\r\n    }\r\n \r\n    return NULL;\r\n}\r\n```\r\n\r\n## Part Main thread:\r\n```c\r\n\t    pthread_t thr;\r\n\t\tif((n = pthread_create(&thr, NULL, &my_thread, NULL)) != 0){\r\n\t\t\terrno = n;\r\n\t\t\tperror(\"pthread_create\");\r\n\t\t\treturn -1;\r\n\t\t}\r\n \r\n        n = 0;\r\n        while (n >= 0 && !force_exit) {\r\n                struct timeval tv;\r\n \r\n                gettimeofday(&tv, NULL);\r\n \r\n                /*\r\n                 * This provokes the LWS_CALLBACK_SERVER_WRITEABLE for every\r\n                 * live websocket connection using the DUMB_INCREMENT protocol,\r\n                 * as soon as it can take more packets (usually immediately)\r\n                 */\r\n\t\t\t\tif(ws_flags_write_all){  /* set only in my_thread */\r\n\t\t\t\t\tms = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);\r\n\t\t\t\t\tif ((ms - oldms) > 50) {\r\n\t\t\t\t\t\tlibwebsocket_callback_on_writable_all_protocol(&protocols[PROTOCOL_DUMB_INCREMENT]);\r\n\t\t\t\t\t\toldms = ms;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n#ifdef EXTERNAL_POLL\r\n \r\n                /*\r\n                 * this represents an existing server's single poll action\r\n                 * which also includes libwebsocket sockets\r\n                 */\r\n \r\n                n = poll(pollfds, count_pollfds, 50);\r\n                if (n < 0)\r\n                        continue;\r\n \r\n \r\n                if (n)\r\n                        for (n = 0; n < count_pollfds; n++)\r\n                                if (pollfds[n].revents)\r\n                                        /*\r\n                                        * returns immediately if the fd does not\r\n                                        * match anything under libwebsockets\r\n                                        * control\r\n                                        */\r\n                                        if (libwebsocket_service_fd(context,\r\n                                                                  &pollfds[n]) < 0)\r\n                                                goto done;\r\n#else\r\n                /*\r\n                 * If libwebsockets sockets are all we care about,\r\n                 * you can use this api which takes care of the poll()\r\n                 * and looping through finding who needed service.\r\n                 *\r\n                 * If no socket needs service, it'll return anyway after\r\n                 * the number of ms in the second argument.\r\n                 */\r\n \r\n                n = libwebsocket_service(context, 50);\r\n#endif\r\n        }\r\n \r\n#ifdef EXTERNAL_POLL\r\ndone:\r\n#endif\r\n \r\n        libwebsocket_context_destroy(context);\r\n \r\n        lwsl_notice(\"libwebsockets-test-server exited cleanly\\n\");\r\n \r\n#ifndef WIN32\r\n        closelog();\r\n#endif\r\n \r\n\t\tpthread_cancel(thr);\r\n\t\tpthread_join(thr, NULL);\r\n \r\n        return 0;\r\n```\r\n\r\n## Console output:\r\n\r\n>lwsts [31255]: libwebsockets test server - (C) Copyright 2010-2014 Andy Green ><andy@warmcat.com> - licensed under LGPL2.1\r\n>Using resource path \"/ home / pi / test-server\"\r\n>lwsts [31255]: Initial logging level 7\r\n>lwsts [31255]: Library version: 1.3 080e6dd\r\n>lwsts [31255]: IPV6 not compiled in\r\n>lwsts [31255]: libev support not compiled in\r\n>lwsts [31255]: static allocation: 4480 + (12 x 1024 fds) = 16768 bytes\r\n>lwsts [31255]: = canonical_hostname raspberrypi\r\n>lwsts [31255]: per-conn Memory: 144 + 2100 + protocol headers rx buf\r\n>lwsts [31255]: Compiled with OpenSSL support\r\n>lwsts [31255]: Using non-SSL mode\r\n>lwsts [31255]: Listening on port 7681\r\n\r\n\r\nModified file test-server.c\r\nhttp://pastebin.com/DMah3jNc\r\n\r\n\r\nThank U"},"comment":{"url":"https://api.github.com/repos/warmcat/libwebsockets/issues/comments/71832728","html_url":"https://github.com/warmcat/libwebsockets/issues/235#issuecomment-71832728","issue_url":"https://api.github.com/repos/warmcat/libwebsockets/issues/235","id":71832728,"user":{"login":"gmmota","id":10728528,"avatar_url":"https://avatars.githubusercontent.com/u/10728528?v=3","gravatar_id":"","url":"https://api.github.com/users/gmmota","html_url":"https://github.com/gmmota","followers_url":"https://api.github.com/users/gmmota/followers","following_url":"https://api.github.com/users/gmmota/following{/other_user}","gists_url":"https://api.github.com/users/gmmota/gists{/gist_id}","starred_url":"https://api.github.com/users/gmmota/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gmmota/subscriptions","organizations_url":"https://api.github.com/users/gmmota/orgs","repos_url":"https://api.github.com/users/gmmota/repos","events_url":"https://api.github.com/users/gmmota/events{/privacy}","received_events_url":"https://api.github.com/users/gmmota/received_events","type":"User","site_admin":false},"created_at":"2015-01-28T13:15:35Z","updated_at":"2015-01-28T13:15:35Z","body":"Compiled without SSL support (-DLWS_WITH_SSL = 0)\r\nand the CPU is not longer tied when called libwebsocket_cancel_service() \r\nfrom another thread (Actually not even have to be from another thread, \r\ncalling on the main thread already has the problem).\r\nI suspect the problem is in the lws-plat-unix.c file when compiling \r\nwith -DLWS_WITH_SSL = 1, lws_plat_service function() on line 111:\r\n```c\r\n#ifdef LWS_OPENSSL_SUPPORT\r\n\t/ * If we know we have non-network pending date, do not wait in poll * /\r\n\tif (context-> ssl_flag_buffered_reads)\r\n\t\ttimeout_ms = 0;\r\n#endif\r\n```\r\nI believe that somehow the timeout is being reset before reaching the poll() function \r\nwhen compiled with OPENSSL _SUPPORT and invoking libwebsocket_cancel_service ().\r\n\r\nThanks\r\n"}}