Skip to content
Snippets Groups Projects
service.c 30.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • 					n = 0;
    					goto handled;
    				}
    			}
    
    			eff_buf.token = NULL;
    			eff_buf.token_len = 0;
    		} while (more);
    
    
    Andy Green's avatar
    Andy Green committed
    		if (wsi->u.hdr.ah) {
    
    			lwsl_info("%s: %p: detaching inherited used ah\n",
    
    Andy Green's avatar
    Andy Green committed
    				 __func__, wsi);
    
    Andy Green's avatar
    Andy Green committed
    			/* show we used all the pending rx up */
    			wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
    			/* we can run the normal ah detach flow despite
    			 * being in ws union mode, since all union members
    			 * start with hdr */
    
    Andy Green's avatar
    Andy Green committed
    			lws_header_table_detach(wsi, 0);
    
    Andy Green's avatar
    Andy Green committed
    		}
    
    
    		pending = lws_ssl_pending(wsi);
    		if (pending) {
    
    			if (lws_is_ws_with_ext(wsi))
    				pending = pending > wsi->u.ws.rx_ubuf_alloc ?
    					wsi->u.ws.rx_ubuf_alloc : pending;
    			else
    				pending = pending > LWS_MAX_SOCKET_IO_BUF ?
    
    Andy Green's avatar
    Andy Green committed
    					LWS_MAX_SOCKET_IO_BUF : pending;
    
    		if (draining_flow && wsi->rxflow_buffer &&
    
    Andy Green's avatar
    Andy Green committed
    		    wsi->rxflow_pos == wsi->rxflow_len) {
    
    			lwsl_info("flow buffer: drained\n");
    
    Andy Green's avatar
    Andy Green committed
    			lws_free_set_NULL(wsi->rxflow_buffer);
    
    			/* having drained the rxflow buffer, can rearm POLLIN */
    
    #ifdef LWS_NO_SERVER
    			n =
    #endif
    
    Andy Green's avatar
    Andy Green committed
    			_lws_rx_flow_control(wsi);
    			/* n ignored, needed for NO_SERVER case */
    
    Andy Green's avatar
    Andy Green committed
    #ifdef LWS_WITH_CGI
    	case LWSCM_CGI: /* we exist to handle a cgi's stdin/out/err data...
    			 * do the callback on our master wsi
    			 */
    		{
    			struct lws_cgi_args args;
    
    			if (wsi->cgi_channel >= LWS_STDOUT &&
    			    !(pollfd->revents & pollfd->events & LWS_POLLIN))
    				break;
    			if (wsi->cgi_channel == LWS_STDIN &&
    			    !(pollfd->revents & pollfd->events & LWS_POLLOUT))
    				break;
    
    			if (wsi->cgi_channel == LWS_STDIN)
    				if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
    					lwsl_info("failed at set pollfd\n");
    					return 1;
    				}
    
    			args.ch = wsi->cgi_channel;
    
    			args.stdwsi = &wsi->parent->cgi->stdwsi[0];
    
    Andy Green's avatar
    Andy Green committed
    			args.hdr_state = wsi->hdr_state;
    
    Andy Green's avatar
    Andy Green committed
    			//lwsl_err("CGI LWS_STDOUT waiting wsi %p mode %d state %d\n",
    			//	 wsi->parent, wsi->parent->mode, wsi->parent->state);
    
    
    Andy Green's avatar
    Andy Green committed
    			if (user_callback_handle_rxflow(
    
    					wsi->parent->protocol->callback,
    					wsi->parent, LWS_CALLBACK_CGI,
    					wsi->parent->user_space,
    
    Andy Green's avatar
    Andy Green committed
    					(void *)&args, 0))
    				return 1;
    
    			break;
    		}
    #endif
    
    	default:
    #ifdef LWS_NO_CLIENT
    		break;
    #else
    		n = lws_client_socket_service(context, wsi, pollfd);
    
    		goto handled;
    #endif
    	}
    
    	n = 0;
    	goto handled;
    
    close_and_handled:
    
    	lwsl_debug("Close and handled\n");
    
    	lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
    
    Andy Green's avatar
    Andy Green committed
    	 * pollfd may point to something else after the close
    	 * due to pollfd swapping scheme on delete on some platforms
    	 * we can't clear revents now because it'd be the wrong guy's revents
    	 */
    
    Andy Green's avatar
    Andy Green committed
    LWS_VISIBLE int
    lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd)
    {
    	return lws_service_fd_tsi(context, pollfd, 0);
    }
    
    
     * lws_service() - Service any pending websocket activity
    
     * @context:	Websocket context
     * @timeout_ms:	Timeout for poll; 0 means return immediately if nothing needed
     *		service otherwise block and service immediately, returning
     *		after the timeout if nothing needed service.
     *
     *	This function deals with any pending websocket traffic, for three
     *	kinds of event.  It handles these events on both server and client
     *	types of connection the same.
     *
     *	1) Accept new connections to our context's server
     *
     *	2) Call the receive callback for incoming frame data received by
     *	    server or client connections.
     *
     *	You need to call this service function periodically to all the above
     *	functions to happen; if your application is single-threaded you can
     *	just call it in your main event loop.
     *
     *	Alternatively you can fork a new process that asynchronously handles
     *	calling this service in a loop.  In that case you are happy if this
     *	call blocks your thread until it needs to take care of something and
     *	would call it with a large nonzero timeout.  Your loop then takes no
     *	CPU while there is nothing happening.
     *
     *	If you are calling it in a single-threaded app, you don't want it to
     *	wait around blocking other things in your loop from happening, so you
     *	would call it with a timeout_ms of 0, so it returns immediately if
     *	nothing is pending, or as soon as it services whatever was pending.
     */
    
    LWS_VISIBLE int
    
    lws_service(struct lws_context *context, int timeout_ms)
    
    {
    	return lws_plat_service(context, timeout_ms);
    }
    
    
    Andy Green's avatar
    Andy Green committed
    LWS_VISIBLE int
    lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
    {
    	return lws_plat_service_tsi(context, timeout_ms, tsi);
    }