int SrsConnection::cycle() { int ret = ERROR_SUCCESS; _srs_context->generate_id(); ip = srs_get_peer_ip(st_netfd_fileno(stfd)); ret = do_cycle(); // if socket io error, set to closed. if (srs_is_client_gracefully_close(ret)) { ret = ERROR_SOCKET_CLOSED; } // success. if (ret == ERROR_SUCCESS) { srs_trace("client finished."); } // client close peer. if (ret == ERROR_SOCKET_CLOSED) { srs_warn("client disconnect peer. ret=%d", ret); } // set loop to stop to quit. pthread->stop_loop(); return ERROR_SUCCESS; }
int SrsEdgeIngester::cycle() { int ret = ERROR_SUCCESS; if ((ret = connect_server()) != ERROR_SUCCESS) { return ret; } srs_assert(client); client->set_recv_timeout(SRS_CONSTS_RTMP_RECV_TIMEOUT_US); client->set_send_timeout(SRS_CONSTS_RTMP_SEND_TIMEOUT_US); SrsRequest* req = _req; if ((ret = client->handshake()) != ERROR_SUCCESS) { srs_error("handshake with server failed. ret=%d", ret); return ret; } if ((ret = client->connect_app(req->app, req->tcUrl, req)) != ERROR_SUCCESS) { srs_error("connect with server failed, tcUrl=%s. ret=%d", req->tcUrl.c_str(), ret); return ret; } if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) { srs_error("connect with server failed, stream_id=%d. ret=%d", stream_id, ret); return ret; } if ((ret = client->play(req->stream, stream_id)) != ERROR_SUCCESS) { srs_error("connect with server failed, stream=%s, stream_id=%d. ret=%d", req->stream.c_str(), stream_id, ret); return ret; } if ((ret = _source->on_publish()) != ERROR_SUCCESS) { srs_error("edge pull stream then publish to edge failed. ret=%d", ret); return ret; } if ((ret = _edge->on_ingest_play()) != ERROR_SUCCESS) { return ret; } ret = ingest(); if (srs_is_client_gracefully_close(ret)) { srs_warn("origin disconnected, retry. ret=%d", ret); ret = ERROR_SUCCESS; } return ret; }
int SrsEdgeIngester::ingest() { int ret = ERROR_SUCCESS; client->set_recv_timeout(SRS_EDGE_INGESTER_TIMEOUT_US); SrsPithyPrint pithy_print(SRS_CONSTS_STAGE_EDGE); while (pthread->can_loop()) { // switch to other st-threads. st_usleep(0); pithy_print.elapse(); // pithy print if (pithy_print.can_print()) { kbps->sample(); srs_trace("<- "SRS_CONSTS_LOG_EDGE_PLAY " time=%"PRId64", okbps=%d,%d,%d, ikbps=%d,%d,%d", pithy_print.age(), kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m()); } // read from client. SrsMessage* msg = NULL; if ((ret = client->recv_message(&msg)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("pull origin server message failed. ret=%d", ret); } return ret; } srs_verbose("edge loop recv message. ret=%d", ret); srs_assert(msg); SrsAutoFree(SrsMessage, msg); if ((ret = process_publish_message(msg)) != ERROR_SUCCESS) { return ret; } } return ret; }
int expect_message(SrsMessage** pmsg, T** ppacket) { *pmsg = NULL; *ppacket = NULL; int ret = ERROR_SUCCESS; while (true) { SrsMessage* msg = NULL; if ((ret = recv_message(&msg)) != ERROR_SUCCESS) { if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) { srs_error("recv message failed. ret=%d", ret); } return ret; } srs_verbose("recv message success."); SrsPacket* packet = NULL; if ((ret = decode_message(msg, &packet)) != ERROR_SUCCESS) { srs_error("decode message failed. ret=%d", ret); srs_freep(msg); srs_freep(packet); return ret; } T* pkt = dynamic_cast<T*>(packet); if (!pkt) { srs_info("drop message(type=%d, size=%d, time=%"PRId64", sid=%d).", msg->header.message_type, msg->header.payload_length, msg->header.timestamp, msg->header.stream_id); srs_freep(msg); srs_freep(packet); continue; } *pmsg = msg; *ppacket = pkt; break; } return ret; }
void SrsThread::thread_cycle() { int ret = ERROR_SUCCESS; _srs_context->generate_id(); srs_info("thread %s cycle start", _name); _cid = _srs_context->get_id(); srs_assert(handler); handler->on_thread_start(); // thread is running now. really_terminated = false; // wait for cid to ready, for parent thread to get the cid. while (!can_run && loop) { st_usleep(10 * 1000); } while (loop) { if ((ret = handler->on_before_cycle()) != ERROR_SUCCESS) { srs_warn("thread %s on before cycle failed, ignored and retry, ret=%d", _name, ret); goto failed; } srs_info("thread %s on before cycle success"); if ((ret = handler->cycle()) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret) && !srs_is_system_control_error(ret)) { srs_warn("thread %s cycle failed, ignored and retry, ret=%d", _name, ret); } goto failed; } srs_info("thread %s cycle success", _name); if ((ret = handler->on_end_cycle()) != ERROR_SUCCESS) { srs_warn("thread %s on end cycle failed, ignored and retry, ret=%d", _name, ret); goto failed; } srs_info("thread %s on end cycle success", _name); failed: if (!loop) { break; } // to improve performance, donot sleep when interval is zero. // @see: https://github.com/ossrs/srs/issues/237 if (cycle_interval_us != 0) { st_usleep(cycle_interval_us); } } // readly terminated now. really_terminated = true; // when thread terminated normally, also disposed. // we must set to disposed before the on_thread_stop, which may free the thread. // @see https://github.com/ossrs/srs/issues/546 disposed = true; handler->on_thread_stop(); srs_info("thread %s cycle finished", _name); }