pike.git / lib / modules / Protocols.pmod / EngineIO.pmod

version» Context lines:

pike.git/lib/modules/Protocols.pmod/EngineIO.pmod:94:    else    client->onrequest(req);    } else    return Server(req);    return 0;   }      class Transport {    final function(int, void|string|Stdio.Buffer:void) read_cb;    final ADT.Queue sendq; -  protected int pingtimeout; +  final protected int pingtimeout; +  final protected Thread.Mutex singleflush = Thread.Mutex(); +  final protected int knock;       protected void create(Protocols.WebSocket.Request req) {    pingtimeout = options->pingTimeout/1000+1;    kickwatchdog();    }       private void droptimeout() {    remove_call_out(close);    }   
pike.git/lib/modules/Protocols.pmod/EngineIO.pmod:253:    break;    }    default:    _req->response_and_finish((["data":"Unsupported method",    "error":Protocols.HTTP.HTTP_METHOD_INVALID,    "extra_heads":(["Allow":"GET,POST,OPTIONS"])]));    }    }       final void flush(void|int type, void|string|Stdio.Buffer msg) { +  do { +  Thread.MutexKey lock = singleflush->trylock(); +  if (lock) { +  knock = 0;    if (req && sendq) { -  while (!sendq->is_empty()) { +  while (knock = 0, !sendq->is_empty()) {    array m = sendq->read();    type = m[0];    msg = m[1];    if (stringp(msg)) {    if (String.width(msg) > 8)    msg = string_to_utf8(msg);    c->add((string)(1+sizeof(msg)))->add_int8(':');    } else if (!forceascii) { -  c->add_int8(1); // 0 would be inefficient, since it passes UTF-8 +  c->add_int8(1); // 0 would be inefficient, since it passes UTF-8    foreach ((string)(1+sizeof(msg));; int i)    c->add_int8(i-'0');    c->add_int8(0xff);    type -= OPEN;    } else {    msg = MIME.encode_base64(msg->read(), 1); -  c->add((string)(1+1+sizeof(msg)))->add_int8(':')->add_int8(BASE64); +  c->add((string)(1+1+sizeof(msg))) +  ->add_int8(':') +  ->add_int8(BASE64);    } -  c->add_int8(m[0])->add(msg); +  c->add_int8(type)->add(msg);    }    if (sizeof(c))    wrapfinish(c->read());    sendqempty();    } -  +  lock = 0; +  } else { +  knock = 1; +  break;    } -  +  } while (knock);    } -  + }      class XHR {    inherit Polling:p;       final protected void getbody(Protocols.WebSocket.Request _req) {    ci->add(_req->body_raw);    }       final protected void wrapfinish(string body) {    respfinish(body, String.range(body)[1]==0xff
pike.git/lib/modules/Protocols.pmod/EngineIO.pmod:339:    con->onclose = close;    t::create(req);    }       final void flush(void|int type, void|string|Stdio.Buffer msg) {    void sendit() {    con->send_text(sprintf("%c%s",type,stringp(msg) ? msg : msg->read()));    };    if (msg)    sendit(); -  else { -  while (!sendq->is_empty()) { +  else +  do { +  Thread.MutexKey lock = singleflush->trylock(); +  if (lock) { +  do +  while (knock = 0, !sendq->is_empty()) {    array m = sendq->read();    type = m[0];    msg = m[1];    sendit();    } -  +  while (knock);    sendqempty(); -  +  lock = 0; +  } else { +  knock = 1; +  break;    } -  +  } while(knock);    }       private void recv(Protocols.WebSocket.Frame f) {    kickwatchdog();    switch (f.opcode) {    case Protocols.WebSocket.FRAME_TEXT:    sb->add(f.text);    break;    case Protocols.WebSocket.FRAME_BINARY:    bb->add(f.data);
pike.git/lib/modules/Protocols.pmod/EngineIO.pmod:428:       //! Send text (string) or binary (Stdio.Buffer) messages.    final void write(string|Stdio.Buffer ... msgs) {    if (state >= SCLOSING)    throw("Socket already shutting down");    foreach (msgs;; string|Stdio.Buffer msg) {    PD("Queue %s %c:%O\n", sid, MESSAGE, (string)msg);    sendq->write(({MESSAGE, msg}));    }    if (state == RUNNING) -  transport->flush(); +  flush();    }       private void send(int type, void|string|Stdio.Buffer msg) {    PD("Queue %s %c:%O\n", sid, type, (string)(msg || ""));    sendq->write(({type, msg || ""}));    switch (state) {    case RUNNING:    case SCLOSING: -  transport->flush(); +  flush();    }    }    -  +  private void flush() { +  transport->flush(); +  } +     private void flushrecvq() {    while (read_cb && !recvq->is_empty())    read_cb(query_id(), recvq->read());    }       //! Close the socket signalling the other side.    final void close() {    if (state < SCLOSING) {    if (close_cb)    close_cb(query_id());
pike.git/lib/modules/Protocols.pmod/EngineIO.pmod:513:    }    }       private void upgrecv(int type, string|Stdio.Buffer msg) {    switch (type) {    default: // Protocol error or CLOSE    upgtransport = 0;    if (state == PAUSED)    state = RUNNING;    if(transport) -  transport->flush(); +  flush();    break;    case PING:    state = PAUSED;    if (!sizeof(sendq))    send(NOOP); -  transport->flush(); +  flush();    upgtransport->flush(PONG, msg);    break;    case UPGRADE: {    upgtransport->read_cb = recv;    transport = upgtransport;    curtransport = "websocket";    if (state == PAUSED)    state = RUNNING;    upgtransport = 0; -  transport->flush(); +  flush();    break;    }    }    }       protected void destroy() {    close();    }       protected void create(Protocols.WebSocket.Request req) {