From be1e774003ed9a93bdf676b4936a8cebb28da997 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Fri, 24 May 2024 19:04:29 +0200 Subject: [PATCH 01/41] [core] New implementation for the logging/formatting system --- srtcore/buffer_snd.cpp | 2 +- srtcore/common.cpp | 15 +- srtcore/core.cpp | 77 +++-- srtcore/logging.cpp | 4 +- srtcore/logging.h | 21 +- srtcore/sfmt.h | 638 +++++++++++++++++++++++++++++++++++++++ srtcore/socketconfig.cpp | 7 +- 7 files changed, 706 insertions(+), 58 deletions(-) create mode 100644 srtcore/sfmt.h diff --git a/srtcore/buffer_snd.cpp b/srtcore/buffer_snd.cpp index ef1bc498c..aaedd702a 100644 --- a/srtcore/buffer_snd.cpp +++ b/srtcore/buffer_snd.cpp @@ -393,7 +393,7 @@ int32_t CSndBuffer::getMsgNoAt(const int offset) { // Prevent accessing the last "marker" block LOGC(bslog.Error, - log << "CSndBuffer::getMsgNoAt: IPE: offset=" << offset << " not found, max offset=" << m_iCount); + log << "CSndBuffer::getMsgNoAt: IPE: offset=" << offset << " not found, max offset=" << m_iCount.load()); return SRT_MSGNO_CONTROL; } diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 6d747ecaa..843420354 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -277,15 +277,12 @@ void srt::CIPAddress::pton(sockaddr_any& w_addr, const uint32_t ip[4], const soc } else { - LOGC(inlog.Error, log << "pton: IPE or net error: can't determine IPv4 carryover format: " << std::hex - << peeraddr16[0] << ":" - << peeraddr16[1] << ":" - << peeraddr16[2] << ":" - << peeraddr16[3] << ":" - << peeraddr16[4] << ":" - << peeraddr16[5] << ":" - << peeraddr16[6] << ":" - << peeraddr16[7] << std::dec); + fmt::obufstream peeraddr_form; + peeraddr_form << fmt::sfmt(peeraddr16[0], "04x"); + for (int i = 1; i < 8; ++i) + peeraddr_form << ":" << fmt::sfmt(peeraddr16[i], "04x"); + + LOGC(inlog.Error, log << "pton: IPE or net error: can't determine IPv4 carryover format: " << peeraddr_form); *target_ipv4_addr = 0; if (peer.family() != AF_INET) { diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 1612830e7..ee76f2bcb 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -88,6 +88,7 @@ using namespace std; using namespace srt; using namespace srt::sync; using namespace srt_logging; +using namespace fmt; const SRTSOCKET UDT::INVALID_SOCK = srt::CUDT::INVALID_SOCK; const int UDT::ERROR = srt::CUDT::ERROR; @@ -424,7 +425,7 @@ void srt::CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen) const int status = m_config.set(optName, optval, optlen); if (status == -1) { - LOGC(aclog.Error, log << CONID() << "OPTION: #" << optName << " UNKNOWN"); + LOGC(aclog.Error, log << CONID() << "OPTION: #" << int(optName) << " UNKNOWN"); throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); } @@ -1035,7 +1036,7 @@ size_t srt::CUDT::fillSrtHandshake(uint32_t *aw_srtdata, size_t srtlen, int msgt if (srtlen < SRT_HS_E_SIZE) { LOGC(cnlog.Fatal, - log << CONID() << "IPE: fillSrtHandshake: buffer too small: " << srtlen << " (expected: " << SRT_HS_E_SIZE << ")"); + log << CONID() << "IPE: fillSrtHandshake: buffer too small: " << srtlen << " (expected: " << int(SRT_HS_E_SIZE) << ")"); return 0; } @@ -1771,10 +1772,14 @@ bool srt::CUDT::createSrtHandshake( if (!m_pCryptoControl && (srtkm_cmd == SRT_CMD_KMREQ || srtkm_cmd == SRT_CMD_KMRSP)) { m_RejectReason = SRT_REJ_IPE; + static const char onoff[2] = {'-', '+'}; LOGC(cnlog.Error, log << CONID() << "createSrtHandshake: IPE: need to send KM, but CryptoControl does not exist." - << " Socket state: connected=" << boolalpha << m_bConnected << ", connecting=" << m_bConnecting - << ", broken=" << m_bBroken << ", closing=" << m_bClosing << "."); + << " Socket state: " + << onoff[m_bConnected] << "connected, " + << onoff[m_bConnecting] << "connecting, " + << onoff[m_bBroken] << "broken, " + << onoff[m_bClosing] << "closing."); return false; } @@ -2102,8 +2107,9 @@ int srt::CUDT::processSrtMsg_HSREQ(const uint32_t *srtdata, size_t bytelen, uint } LOGC(cnlog.Debug, log << "HSREQ/rcv: cmd=" << SRT_CMD_HSREQ << "(HSREQ) len=" << bytelen - << hex << " vers=0x" << srtdata[SRT_HS_VERSION] << " opts=0x" << srtdata[SRT_HS_FLAGS] - << dec << " delay=" << SRT_HS_LATENCY_RCV::unwrap(srtdata[SRT_HS_LATENCY])); + << " vers=0x" << sfmt(srtdata[SRT_HS_VERSION], "x") + << " opts=0x" << sfmt(srtdata[SRT_HS_FLAGS], "x") + << " delay=" << SRT_HS_LATENCY_RCV::unwrap(srtdata[SRT_HS_LATENCY])); m_uPeerSrtVersion = srtdata[SRT_HS_VERSION]; m_uPeerSrtFlags = srtdata[SRT_HS_FLAGS]; @@ -2522,7 +2528,7 @@ bool srt::CUDT::interpretSrtHandshake(const CHandShake& hs, m_RejectReason = SRT_REJ_ROGUE; LOGC(cnlog.Error, log << CONID() << "HS-ext HSREQ found but invalid size: " << bytelen - << " (expected: " << SRT_HS_E_SIZE << ")"); + << " (expected: " << int(SRT_HS_E_SIZE) << ")"); return false; // don't interpret } @@ -2548,7 +2554,7 @@ bool srt::CUDT::interpretSrtHandshake(const CHandShake& hs, m_RejectReason = SRT_REJ_ROGUE; LOGC(cnlog.Error, log << CONID() << "HS-ext HSRSP found but invalid size: " << bytelen - << " (expected: " << SRT_HS_E_SIZE << ")"); + << " (expected: " << int(SRT_HS_E_SIZE) << ")"); return false; // don't interpret } @@ -3451,7 +3457,7 @@ void srt::CUDT::synchronizeWithGroup(CUDTGroup* gp) { HLOGC(gmlog.Debug, log << CONID() << "synchronizeWithGroup: DERIVED ISN: RCV=%" << m_iRcvLastAck << " -> %" << rcv_isn - << " (shift by " << CSeqNo::seqcmp(rcv_isn, m_iRcvLastAck) << ") SND=%" << m_iSndLastAck + << " (shift by " << CSeqNo::seqcmp(rcv_isn, m_iRcvLastAck) << ") SND=%" << m_iSndLastAck.load() << " -> %" << snd_isn << " (shift by " << CSeqNo::seqcmp(snd_isn, m_iSndLastAck) << ")"); setInitialRcvSeq(rcv_isn); setInitialSndSeq(snd_isn); @@ -3460,7 +3466,7 @@ void srt::CUDT::synchronizeWithGroup(CUDTGroup* gp) { HLOGC(gmlog.Debug, log << CONID() << "synchronizeWithGroup: DEFINED ISN: RCV=%" << m_iRcvLastAck << " SND=%" - << m_iSndLastAck); + << m_iSndLastAck.load()); } } #endif @@ -4098,11 +4104,16 @@ EConnectStatus srt::CUDT::craftKmResponse(uint32_t* aw_kmdata, size_t& w_kmdatas // m_pCryptoControl can be NULL if the socket has been closed already. See issue #2231. if (!m_pCryptoControl) { + static const char onoff[2] = {'-', '+'}; m_RejectReason = SRT_REJ_IPE; LOGC(cnlog.Error, log << CONID() << "IPE: craftKmResponse needs to send KM, but CryptoControl does not exist." - << " Socket state: connected=" << boolalpha << m_bConnected << ", connecting=" << m_bConnecting - << ", broken=" << m_bBroken << ", opened " << m_bOpened << ", closing=" << m_bClosing << "."); + << " Socket state: " + << onoff[m_bConnected] << "connected, " + << onoff[m_bConnecting] << "connecting, " + << onoff[m_bBroken] << "broken, " + << onoff[m_bOpened] << "opened, " + << onoff[m_bClosing] << "closing."); return CONN_REJECT; } // This is a periodic handshake update, so you need to extract the KM data from the @@ -5466,8 +5477,8 @@ void * srt::CUDT::tsbpd(void* param) if (self->frequentLogAllowed(FREQLOGFA_RCV_DROPPED, tnow, (why))) { LOGC(brlog.Warn, log << self->CONID() << "RCV-DROPPED " << iDropCnt << " packet(s). Packet seqno %" << info.seqno - << " delayed for " << (timediff_us / 1000) << "." << std::setw(3) << std::setfill('0') - << (timediff_us % 1000) << " ms " << why); + << " delayed for " << (timediff_us / 1000) << "." + << sfmt(timediff_us % 1000, "03") << " ms " << why); } #if SRT_ENABLE_FREQUENT_LOG_TRACE else @@ -6573,7 +6584,7 @@ int srt::CUDT::sndDropTooLate() } HLOGC(qslog.Debug, - log << CONID() << "SND-DROP: %(" << realack << "-" << m_iSndCurrSeqNo << ") n=" << dpkts << "pkt " << dbytes + log << CONID() << "SND-DROP: %(" << realack << "-" << m_iSndCurrSeqNo.load() << ") n=" << dpkts << "pkt " << dbytes << "B, span=" << buffdelay_ms << " ms, FIRST #" << first_msgno); #if ENABLE_BONDING @@ -8408,7 +8419,7 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ // included, but it also triggers for any other kind of invalid value. // This check MUST BE DONE before making any operation on this number. LOGC(inlog.Error, log << CONID() << "ACK: IPE/EPE: received invalid ACK value: " << ackdata_seqno - << " " << std::hex << ackdata_seqno << " (IGNORED)"); + << " " << sfmt(ackdata_seqno, "x") << " (IGNORED)"); return; } @@ -8465,7 +8476,7 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ // this should not happen: attack or bug LOGC(gglog.Error, log << CONID() << "ATTACK/IPE: incoming ack seq " << ackdata_seqno << " exceeds current " - << m_iSndCurrSeqNo << " by " << (CSeqNo::seqoff(m_iSndCurrSeqNo, ackdata_seqno) - 1) << "!"); + << m_iSndCurrSeqNo.load() << " by " << (CSeqNo::seqoff(m_iSndCurrSeqNo, ackdata_seqno) - 1) << "!"); m_bBroken = true; m_iBrokenCounter = 0; return; @@ -8667,14 +8678,14 @@ void srt::CUDT::processCtrlAckAck(const CPacket& ctrlpkt, const time_point& tsAr LOGC(inlog.Note, log << CONID() << "ACKACK out of order, skipping RTT calculation " << "(ACK number: " << ctrlpkt.getAckSeqNo() << ", last ACK sent: " << m_iAckSeqNo - << ", RTT (EWMA): " << m_iSRTT << ")"); + << ", RTT (EWMA): " << m_iSRTT.load() << ")"); return; } LOGC(inlog.Error, log << CONID() << "ACK record not found, can't estimate RTT " << "(ACK number: " << ctrlpkt.getAckSeqNo() << ", last ACK sent: " << m_iAckSeqNo - << ", RTT (EWMA): " << m_iSRTT << ")"); + << ", RTT (EWMA): " << m_iSRTT.load() << ")"); return; } @@ -8777,7 +8788,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) // LO must not be greater than HI. // HI must not be greater than the most recent sent seq. LOGC(inlog.Warn, log << CONID() << "rcv LOSSREPORT rng " << losslist_lo << " - " << losslist_hi - << " with last sent " << m_iSndCurrSeqNo << " - DISCARDING"); + << " with last sent " << m_iSndCurrSeqNo.load() << " - DISCARDING"); secure = false; wrong_loss = losslist_hi; break; @@ -8846,7 +8857,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) if (CSeqNo::seqcmp(losslist[i], m_iSndCurrSeqNo) > 0) { LOGC(inlog.Warn, log << CONID() << "rcv LOSSREPORT pkt %" << losslist[i] - << " with last sent %" << m_iSndCurrSeqNo << " - DISCARDING"); + << " with last sent %" << m_iSndCurrSeqNo.load() << " - DISCARDING"); // loss_seq must not be greater than the most recent sent seq secure = false; wrong_loss = losslist[i]; @@ -8882,7 +8893,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) if (!secure) { LOGC(inlog.Warn, - log << CONID() << "out-of-band LOSSREPORT received; BUG or ATTACK - last sent %" << m_iSndCurrSeqNo + log << CONID() << "out-of-band LOSSREPORT received; BUG or ATTACK - last sent %" << m_iSndCurrSeqNo.load() << " vs loss %" << wrong_loss); // this should not happen: attack or bug m_bBroken = true; @@ -9074,7 +9085,7 @@ void srt::CUDT::processCtrlDropReq(const CPacket& ctrlpkt) else { HLOGC(inlog.Debug, log << CONID() << "DROPREQ: dropping %" - << dropdata[0] << "-" << dropdata[1] << " current %" << m_iRcvCurrSeqNo); + << dropdata[0] << "-" << dropdata[1] << " current %" << m_iRcvCurrSeqNo.load()); } } @@ -9322,7 +9333,7 @@ int srt::CUDT::packLostData(CPacket& w_packet) // was completely ignored. LOGC(qrlog.Error, log << CONID() << "IPE/EPE: packLostData: LOST packet negative offset: seqoff(seqno() " - << w_packet.seqno() << ", m_iSndLastDataAck " << m_iSndLastDataAck << ")=" << offset + << w_packet.seqno() << ", m_iSndLastDataAck " << m_iSndLastDataAck.load() << ")=" << offset << ". Continue, request DROP"); // No matter whether this is right or not (maybe the attack case should be @@ -9747,7 +9758,7 @@ bool srt::CUDT::packUniqueData(CPacket& w_packet) { HLOGC(qslog.Debug, log << CONID() << "packUniqueData: CONGESTED: cwnd=min(" << m_iFlowWindowSize << "," << m_iCongestionWindow - << ")=" << cwnd << " seqlen=(" << m_iSndLastAck << "-" << m_iSndCurrSeqNo << ")=" << flightspan); + << ")=" << cwnd << " seqlen=(" << m_iSndLastAck << "-" << m_iSndCurrSeqNo.load() << ")=" << flightspan); return false; } @@ -9763,7 +9774,7 @@ bool srt::CUDT::packUniqueData(CPacket& w_packet) { // Some packets were skipped due to TTL expiry. m_iSndCurrSeqNo = CSeqNo::incseq(m_iSndCurrSeqNo, pktskipseqno); - HLOGC(qslog.Debug, log << "packUniqueData: reading skipped " << pktskipseqno << " seq up to %" << m_iSndCurrSeqNo + HLOGC(qslog.Debug, log << "packUniqueData: reading skipped " << pktskipseqno << " seq up to %" << m_iSndCurrSeqNo.load() << " due to TTL expiry"); } @@ -9967,7 +9978,7 @@ bool srt::CUDT::overrideSndSeqNo(int32_t seq) if (diff < 0 || diff > CSeqNo::m_iSeqNoTH) { LOGC(gslog.Error, log << CONID() << "IPE: Overriding with seq %" << seq << " DISCREPANCY against current %" - << m_iSndCurrSeqNo << " and next sched %" << m_iSndNextSeqNo << " - diff=" << diff); + << m_iSndCurrSeqNo.load() << " and next sched %" << m_iSndNextSeqNo.load() << " - diff=" << diff); return false; } @@ -9984,7 +9995,7 @@ bool srt::CUDT::overrideSndSeqNo(int32_t seq) // not yet sent. HLOGC(gslog.Debug, - log << CONID() << "overrideSndSeqNo: sched-seq=" << m_iSndNextSeqNo << " send-seq=" << m_iSndCurrSeqNo + log << CONID() << "overrideSndSeqNo: sched-seq=" << m_iSndNextSeqNo.load() << " send-seq=" << m_iSndCurrSeqNo.load() << " (unchanged)"); return true; } @@ -10107,7 +10118,7 @@ int srt::CUDT::handleSocketPacketReception(const vector& incoming, bool& "SEQUENCE DISCREPANCY. BREAKING CONNECTION." " %" << rpkt.seqno() << " buffer=(%" << bufseq - << ":%" << m_iRcvCurrSeqNo // -1 = size to last index + << ":%" << m_iRcvCurrSeqNo.load() // -1 = size to last index << "+%" << CSeqNo::incseq(bufseq, int(m_pRcvBuffer->capacity()) - 1) << "), " << (m_pRcvBuffer->capacity() - bufidx + 1) << " past max. Reception no longer possible. REQUESTING TO CLOSE."); @@ -10227,7 +10238,7 @@ int srt::CUDT::handleSocketPacketReception(const vector& incoming, bool& bufinfo << " BUF.s=" << m_pRcvBuffer->capacity() << " avail=" << (int(m_pRcvBuffer->capacity()) - ackidx) << " buffer=(%" << bufseq - << ":%" << m_iRcvCurrSeqNo // -1 = size to last index + << ":%" << m_iRcvCurrSeqNo.load() // -1 = size to last index << "+%" << CSeqNo::incseq(bufseq, int(m_pRcvBuffer->capacity()) - 1) << ")"; } @@ -10725,7 +10736,7 @@ void srt::CUDT::updateIdleLinkFrom(CUDT* source) { // Reject the change because that would shift the reception pointer backwards. HLOGC(grlog.Debug, log << "grp: NOT updating rcv-seq in @" << m_SocketID - << ": backward setting rejected: %" << m_iRcvCurrSeqNo + << ": backward setting rejected: %" << m_iRcvCurrSeqNo.load() << " -> %" << new_last_rcv); return; } @@ -11220,7 +11231,7 @@ int srt::CUDT::processConnectRequest(const sockaddr_any& addr, CPacket& packet) if (result == -1) { hs.m_iReqType = URQFailure(error); - LOGC(cnlog.Warn, log << "processConnectRequest: rsp(REJECT): " << hs.m_iReqType << " - " << srt_rejectreason_str(error)); + LOGC(cnlog.Warn, log << "processConnectRequest: rsp(REJECT): " << int(hs.m_iReqType) << " - " << srt_rejectreason_str(error)); } // The `acpu` not NULL means connection exists, the `result` should be 0. It is not checked here though. @@ -11324,7 +11335,7 @@ int srt::CUDT::processConnectRequest(const sockaddr_any& addr, CPacket& packet) } } } - LOGC(cnlog.Debug, log << CONID() << "listen ret: " << hs.m_iReqType << " - " << RequestTypeStr(hs.m_iReqType)); + LOGC(cnlog.Debug, log << CONID() << "listen ret: " << int(hs.m_iReqType) << " - " << RequestTypeStr(hs.m_iReqType)); return RejectReasonForURQ(hs.m_iReqType); } diff --git a/srtcore/logging.cpp b/srtcore/logging.cpp index d0ba3fd4a..8ccfa30f1 100644 --- a/srtcore/logging.cpp +++ b/srtcore/logging.cpp @@ -43,7 +43,7 @@ LogDispatcher::Proxy LogDispatcher::operator()() return Proxy(*this); } -void LogDispatcher::CreateLogLinePrefix(std::ostringstream& serr) +void LogDispatcher::CreateLogLinePrefix(fmt::obufstream& serr) { using namespace std; using namespace srt; @@ -60,7 +60,7 @@ void LogDispatcher::CreateLogLinePrefix(std::ostringstream& serr) if (strftime(tmp_buf, sizeof(tmp_buf), "%X.", &tm)) { - serr << tmp_buf << setw(6) << setfill('0') << tv.tv_usec; + serr << tmp_buf << fmt::sfmt(tv.tv_usec, "06"); } } diff --git a/srtcore/logging.h b/srtcore/logging.h index 2ec5f46aa..0917af9ac 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -20,7 +20,6 @@ written by #include #include #include -#include #include #ifdef _WIN32 #include "win/wintime.h" @@ -29,6 +28,8 @@ written by #include #endif +#include "sfmt.h" + #include "srt.h" #include "utilities.h" #include "threadname.h" @@ -192,7 +193,7 @@ struct SRT_API LogDispatcher bool CheckEnabled(); - void CreateLogLinePrefix(std::ostringstream&); + void CreateLogLinePrefix(fmt::obufstream&); void SendLogLine(const char* file, int line, const std::string& area, const std::string& sl); // log.Debug("This is the ", nth, " time"); <--- C++11 only. @@ -285,7 +286,7 @@ struct LogDispatcher::Proxy { LogDispatcher& that; - std::ostringstream os; + fmt::obufstream os; // Cache the 'enabled' state in the beginning. If the logging // becomes enabled or disabled in the middle of the log, we don't @@ -341,7 +342,7 @@ struct LogDispatcher::Proxy if ( that_enabled ) { if ( (flags & SRT_LOGF_DISABLE_EOL) == 0 ) - os << std::endl; + os << fmt::seol; that.SendLogLine(i_file, i_line, area, os.str()); } // Needed in destructor? @@ -435,10 +436,10 @@ inline bool LogDispatcher::CheckEnabled() //extern std::mutex Debug_mutex; -inline void PrintArgs(std::ostream&) {} +inline void PrintArgs(fmt::obufstream&) {} template -inline void PrintArgs(std::ostream& serr, Arg1&& arg1, Args&&... args) +inline void PrintArgs(fmt::obufstream& serr, Arg1&& arg1, Args&&... args) { serr << std::forward(arg1); PrintArgs(serr, args...); @@ -448,12 +449,12 @@ template inline void LogDispatcher::PrintLogLine(const char* file SRT_ATR_UNUSED, int line SRT_ATR_UNUSED, const std::string& area SRT_ATR_UNUSED, Args&&... args SRT_ATR_UNUSED) { #ifdef ENABLE_LOGGING - std::ostringstream serr; + fmt::obufstream serr; CreateLogLinePrefix(serr); PrintArgs(serr, args...); if ( !isset(SRT_LOGF_DISABLE_EOL) ) - serr << std::endl; + serr << fmt::seol; // Not sure, but it wasn't ever used. SendLogLine(file, line, area, serr.str()); @@ -466,12 +467,12 @@ template inline void LogDispatcher::PrintLogLine(const char* file SRT_ATR_UNUSED, int line SRT_ATR_UNUSED, const std::string& area SRT_ATR_UNUSED, const Arg& arg SRT_ATR_UNUSED) { #ifdef ENABLE_LOGGING - std::ostringstream serr; + fmt::obufstream serr; CreateLogLinePrefix(serr); serr << arg; if ( !isset(SRT_LOGF_DISABLE_EOL) ) - serr << std::endl; + serr << fmt::seol; // Not sure, but it wasn't ever used. SendLogLine(file, line, area, serr.str()); diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h new file mode 100644 index 000000000..8eda16462 --- /dev/null +++ b/srtcore/sfmt.h @@ -0,0 +1,638 @@ +// Formatting library for C++ - C++03 compat version of on-demand tagged format API. +// +// Copyright (c) 2024 - present, Mikołaj Małecki +// All rights reserved. +// +// For the license information refer to format.h. + +// This is a header-only lightweight C++03-compatible formatting library, +// which provides the on-demand tagged format API and iostream-style wrapper +// for FILE type from stdio. It has nothing to do with the rest of the {fmt} +// library, except that it reuses the namespace. + +#include +#include +#include +#include +#include + +namespace fmt +{ + +namespace internal +{ + +template +class form_memory_buffer +{ +public: + static const size_t INITIAL_SIZE = PARAM_INITIAL_SIZE; + typedef std::list< std::vector > slices_t; + +private: + char first[INITIAL_SIZE]; + slices_t slices; + + size_t initial; // size used in `first` + size_t reserved; // total size plus slices in reserve + size_t total; // total size in use + +public: + form_memory_buffer(): initial(0), reserved(0), total(0) {} + + // For constants + template + form_memory_buffer(const char (&array)[N]): initial(N-1), reserved(N-1), total(N-1) + { + memcpy(first, array, N); + } + + size_t avail() + { + return reserved - total; + } + + char* get_first() { return first; } + const char* get_first() const { return first; } + size_t first_size() const { return initial; } + const slices_t& get_slices() const { return slices; } + size_t size() const { return total; } + bool empty() const { return total == 0; } + + void append(char c) + { + char wrap[1] = {c}; + append(wrap, 1); + } + + // NOTE: append ignores the reservation. It writes + // where the currently available space is. Use expose() + // and commit() together or not at all. + void append(const char* val, size_t size) + { + if (size == 0) + return; + + if (slices.empty()) + { + if (size < INITIAL_SIZE - initial) + { + // Still free space in first. + memcpy(first + initial, val, size); + initial += size; + total = initial; + if (reserved < total) + reserved = total; + return; + } + } + + slices.push_back(std::vector(val, val+size)); + total += size; + if (reserved < total) + reserved = total; + } + + char* expose(size_t size) + { + // Repeated exposure simply extends the + // reservation, if required more, or is ignored, + // if required less. + + // Note that ort + + size_t already_reserved = reserved - total; + if (already_reserved >= size) + { + // Identify the reserved region + if (slices.empty()) + { + reserved = total + size; + return first + initial; + } + + std::vector& last = slices.back(); + // Exceptionally resize that part if it doesn't + // fit. + if (last.size() != size) + last.resize(size); + reserved = total + size; + return &last[0]; + } + + // Check if you have any size available + // beyond the current reserved space. + // If not, allocate. + if (slices.empty()) + { + // Not yet resolved to use of the slices, + // so check free space in first. The value of + // 'reserved' should be still < INITIAL_SIZE. + if (INITIAL_SIZE - total >= size) + { + char* b = first + total; + reserved = total + size; + return b; + } + } + + // Otherwise allocate a new slice + // Check first if the last slice was already reserved + std::vector* plast = &slices.back(); + if (!already_reserved) + { + slices.push_back( std::vector() ); + plast = &slices.back(); + } + + plast->reserve(size); + plast->resize(size); + reserved = total + size; + return &(*plast)[0]; + } + + // Remove the last 'size' chars from reservation + bool unreserve(size_t size) + { + if (size > reserved - total) + return false; + + if (!slices.empty()) + { + // Check the last slice if it contains that size + std::vector& last = slices.back(); + if (last.size() < size) + return false; + + size_t remain = last.size() - size; + if (!remain) + { + slices.pop_back(); + reserved -= size; + return true; + } + + last.erase(last.begin() + remain, last.end()); + } + // Otherwise the space is in the initial buffer. + + reserved -= size; + return true; + } + + void commit() + { + total = reserved; + if (slices.empty()) + { + // This means we don't use extra slices, so + // this size must be also repeated in initial + initial = reserved; + } + } +}; + +template +struct CheckChar +{ + static bool is(char c, const char (&series)[N]) + { + return c == series[I] || CheckChar::is(c, series); + } +}; + +template +struct CheckChar +{ + // Terminal version - if none interrupted with true, + // eventually return false. + static bool is(char , const char (&)[N]) { return false; } +}; + +template inline +bool isanyof(char c, const char (&series)[N]) +{ + return CheckChar::is(c, series); +} + +template inline +bool isnum_or(char c, const char (&series)[N]) +{ + if (c >= '0' && c <= '9') + return true; + return isanyof(c, series); +} + +template +struct Ensure +{ +}; + +template +struct Ensure +{ + typename AnyType::wrong_condition v = AnyType::wrong_condition; +}; + +template inline +form_memory_buffer<> fix_format(const char* fmt, + const char (&allowed)[N1], + const char (&typed)[N2], + const char (&deftype)[N3], + const char* warn) +{ + // All these arrays must contain at least 2 elements, + // that is one character and terminating zero. + //Ensure= 2> c1; + Ensure= 2> c2; (void)c2; + Ensure= 2> c3; (void)c3; + + form_memory_buffer<> buf; + buf.append('%'); + + bool warn_error = false; + if (fmt) + { + size_t len = strlen(fmt); + for (size_t i = 0; i < len; ++i) + { + char c = fmt[i]; + if (internal::isnum_or(c, allowed)) + { + buf.append(c); + continue; + } + + if (internal::isanyof(c, typed)) + { + // If you have found any numbase character, + // add first all characters from the default, + // EXCEPT the last one. + buf.append(deftype, N3-2); + + // that's it, and we're done here. + buf.append(c); + return buf; + } + + // If any other character is found, add the warning + warn_error = true; + break; + } + } + + buf.append(deftype, N3); + + if (warn_error && warn) + { + buf.append(warn, strlen(warn)); + } + return buf; +} + + +template +struct Formatter +{ +}; + +#define SFMT_FORMAT_FIXER_TPL(tplarg, type, allowed, typed, deftype, warn)\ +template \ +struct Formatter \ +{ \ + static form_memory_buffer<> fix(const char* fmt) \ + { \ + return internal::fix_format(fmt, allowed, typed, deftype, warn); \ + } \ +} +#define SFMT_FORMAT_FIXER(type, allowed, typed, deftype, warn) \ + SFMT_FORMAT_FIXER_TPL(, type, allowed, typed, deftype, warn) + + +// So, format in the format spec is: +// +// (missing): add the default format +// Using: diouxX - specify the numeric base +// Using efg - specify the float style + +// Modifiers like "h", "l", or "L" shall not +// be used. They will be inserted if needed. + +SFMT_FORMAT_FIXER(int, "+- '#", "dioxX", "i", ""); +// Short is simple because it's aligned to int anyway +SFMT_FORMAT_FIXER(short int, "+- '#", "dioxX", "hi", ""); + +SFMT_FORMAT_FIXER(long int, "+- '#", "dioxX", "li", ""); + +SFMT_FORMAT_FIXER(long long int, "+- '#", "dioxX", "lli", ""); + +SFMT_FORMAT_FIXER(unsigned int, "+- '#", "uoxX", "u", ""); + +SFMT_FORMAT_FIXER(unsigned short int, "+- '#", "uoxX", "hu", ""); + +SFMT_FORMAT_FIXER(unsigned long int, "+- '#", "uoxX", "lu", ""); + +SFMT_FORMAT_FIXER(unsigned long long int, "+- '#", "uoxX", "llu", ""); + +SFMT_FORMAT_FIXER(double, "+- '#.", "EeFfgGaA", "g", ""); +SFMT_FORMAT_FIXER(float, "+- '#.", "EeFfgGaA", "g", ""); +SFMT_FORMAT_FIXER(long double, "+- '#.", "EeFfgGaA", "Lg", ""); + +SFMT_FORMAT_FIXER(char, "", "c", "c", ""); +SFMT_FORMAT_FIXER(std::string, "", "s", "s", ""); +SFMT_FORMAT_FIXER(const char*, "", "s", "s", ""); +SFMT_FORMAT_FIXER(char*, "", "s", "s", ""); +SFMT_FORMAT_FIXER_TPL(size_t N, const char[N], "", "s", "s", ""); +SFMT_FORMAT_FIXER_TPL(size_t N, char[N], "", "s", "s", ""); +SFMT_FORMAT_FIXER_TPL(class Type, Type*, "", "p", "p", ""); + +#undef SFMT_FORMAT_FIXER_TPL +#undef SFMT_FORMAT_FIXER + +template inline +void write_default(Stream& str, const Value& val); + +} + +class ostdiostream +{ +protected: + mutable FILE* in; + +public: + + FILE* raw() const { return in; } + + ostdiostream(FILE* f): in(f) {} + + ostdiostream& operator<<(const char* t) + { + std::fputs(t, in); + return *this; + } + + ostdiostream& operator<<(const std::string& s) + { + std::fputs(s.c_str(), in); + return *this; + } + + template + ostdiostream& operator<<(const internal::form_memory_buffer& b) + { + using namespace internal; + // Copy all pieces one by one + if (b.size() == 0) + return *this; + + std::fwrite(b.get_first(), 1, b.first_size(), in); + for (form_memory_buffer<>::slices_t::const_iterator i = b.get_slices().begin(); + i != b.get_slices().end(); ++i) + { + const char* data = &(*i)[0]; + std::fwrite(data, 1, i->size(), in); + } + return *this; + } + + template + ostdiostream& operator<<(const Value& v) + { + internal::write_default(*this, v); + return *this; + } +}; + + +class ofilestream: public ostdiostream +{ +public: + + ofilestream(): ostdiostream(0) {} + + ofilestream(const std::string& name, const std::string& mode = "") + : ostdiostream(0) // Set NULL initially, but then override + { + open(name, mode); + } + + bool good() const { return in; } + + void open(const std::string& name, const std::string& mode = "") + { + if (mode == "") + in = std::fopen(name.c_str(), "w"); + else + in = std::fopen(name.c_str(), mode.c_str()); + } + + // For the use of other functions than fopen() that can create the stream, + // but they still create FILE* that should be closed using fclose(). + void attach(FILE* other) + { + in = other; + } + + FILE* detach() + { + FILE* sav = in; + in = 0; + return sav; + } + + int close() + { + int retval = 0; + if (in) + { + retval = std::fclose(in); + in = 0; + } + return retval; + } + + ~ofilestream() + { + if (in) + std::fclose(in); + } +}; + +class obufstream +{ +protected: + internal::form_memory_buffer<> buffer; + +public: + + obufstream() {} + + obufstream& operator<<(const char* t) + { + size_t len = strlen(t); + buffer.append(t, len); + return *this; + } + + obufstream& operator<<(const std::string& s) + { + buffer.append(s.data(), s.size()); + return *this; + } + + template + obufstream& operator<<(const internal::form_memory_buffer& b) + { + using namespace internal; + // Copy all pieces one by one + if (b.size() == 0) + return *this; + + buffer.append(b.get_first(), b.first_size()); + for (form_memory_buffer<>::slices_t::const_iterator i = b.get_slices().begin(); + i != b.get_slices().end(); ++i) + { + // Would be tempting to move the blocks, but C++03 doesn't feature moving. + const char* data = &(*i)[0]; + buffer.append(data, i->size()); + } + return *this; + } + + obufstream& operator<<(const obufstream& source) + { + return *this << source.buffer; + } + + template + obufstream& operator<<(const Value& v) + { + internal::write_default(*this, v); + return *this; + } + + std::string str() const + { + using namespace internal; + std::string out; + if (buffer.empty()) + return out; + + out.reserve(buffer.size() + 1); + out.append(buffer.get_first(), buffer.first_size()); + for (form_memory_buffer<>::slices_t::const_iterator i = buffer.get_slices().begin(); + i != buffer.get_slices().end(); ++i) + { + // Would be tempting to move the blocks, but C++03 doesn't feature moving. + const char* data = &(*i)[0]; + out.append(data, i->size()); + } + return out; + } + + size_t size() const { return buffer.size(); } + + template + void copy_to(OutputContainer& out) const + { + using namespace internal; + + std::copy(buffer.get_first(), buffer.get_first() + buffer.first_size(), + std::back_inserter(out)); + + for (form_memory_buffer<>::slices_t::const_iterator i = buffer.get_slices().begin(); + i != buffer.get_slices().end(); ++i) + { + // Would be tempting to move the blocks, but C++03 doesn't feature moving. + const char* data = &(*i)[0]; + std::copy(data, data + i->size(), std::back_inserter(out)); + } + } +}; + +template inline +internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) +{ + using namespace internal; + + form_memory_buffer<> fstr = Formatter::fix(fmtspec); + form_memory_buffer<> out; + size_t bufsize = form_memory_buffer<>::INITIAL_SIZE; + + // Reserve the maximum initial first, then shrink. + char* buf = out.expose(bufsize); + + // We want to use this buffer as a NUL-terminated string. + // So we need to add NUL character oursevles, form_memory_buffer<> + // doesn't do it an doesn't use the NUL-termination. + fstr.append('\0'); + + size_t valsize = snprintf(buf, bufsize, fstr.get_first(), val); + + // Deemed impossible to happen, but still + if (valsize == bufsize) + { + bufsize *= 2; + // Just try again with one extra size, if this won't + // suffice, just add <...> at the end. + buf = out.expose(bufsize); + valsize = snprintf(buf, bufsize, fstr.get_first(), val); + if (valsize == bufsize) + { + char* end = buf + bufsize - 6; + strcpy(end, "<...>"); + } + } + + size_t unused = bufsize - valsize; + out.unreserve(unused); + out.commit(); + return out; +} + +template inline +std::string sfmts(const Value& val, const char* fmtspec = 0) +{ + using namespace internal; + + std::string out; + form_memory_buffer<> b = sfmt(val, fmtspec); + if (b.size() == 0) + return out; + + out.reserve(b.size()); + + out.append(b.get_first(), b.first_size()); + for (form_memory_buffer<>::slices_t::const_iterator i = b.get_slices().begin(); + i != b.get_slices().end(); ++i) + { + const char* data = &(*i)[0]; + out.append(data, i->size()); + } + + return out; +} + +namespace internal +{ +template inline +void write_default(Stream& s, const Value& v) +{ + s << sfmt(v, ""); +} +} + +// Semi-manipulator to add the end-of-line. +const internal::form_memory_buffer<2> seol ("\n"); + +// Another manipulator. You can add yourself others the same way. +const struct os_flush_manip {} sflush; + +inline ostdiostream& operator<<(ostdiostream& sout, const os_flush_manip&) +{ + std::fflush(sout.raw()); + return sout; +}; + + +} diff --git a/srtcore/socketconfig.cpp b/srtcore/socketconfig.cpp index d44330f78..9c5a9513e 100644 --- a/srtcore/socketconfig.cpp +++ b/srtcore/socketconfig.cpp @@ -744,8 +744,8 @@ struct CSrtConfigSetter { co.uKmPreAnnouncePkt = (km_refresh - 1) / 2; LOGC(aclog.Warn, - log << "SRTO_KMREFRESHRATE=0x" << std::hex << km_refresh << ": setting SRTO_KMPREANNOUNCE=0x" - << std::hex << co.uKmPreAnnouncePkt); + log << "SRTO_KMREFRESHRATE=0x" << fmt::sfmt(km_refresh, "x") << ": setting SRTO_KMPREANNOUNCE=0x" + << fmt::sfmt(co.uKmPreAnnouncePkt, "x")); } } }; @@ -770,7 +770,8 @@ struct CSrtConfigSetter if (km_preanno > (kmref - 1) / 2) { LOGC(aclog.Error, - log << "SRTO_KMPREANNOUNCE=0x" << std::hex << km_preanno << " exceeds KmRefresh/2, 0x" << ((kmref - 1) / 2) + log << "SRTO_KMPREANNOUNCE=0x" << fmt::sfmt(km_preanno, "x") + << " exceeds KmRefresh/2, 0x" << fmt::sfmt((kmref - 1) / 2) << " - OPTION REJECTED."); throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); } From 308af582cbb21ca38ac83c9bf6c04000a03f32bf Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Fri, 24 May 2024 19:22:07 +0200 Subject: [PATCH 02/41] Fixed parts in non-default-enabled code parts --- srtcore/buffer_snd.cpp | 2 +- srtcore/core.cpp | 6 +++--- srtcore/group.cpp | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/srtcore/buffer_snd.cpp b/srtcore/buffer_snd.cpp index aaedd702a..998e080ab 100644 --- a/srtcore/buffer_snd.cpp +++ b/srtcore/buffer_snd.cpp @@ -141,7 +141,7 @@ void CSndBuffer::addBuffer(const char* data, int len, SRT_MSGCTRL& w_mctrl) const int iNumBlocks = countNumPacketsRequired(len, iPktLen); HLOGC(bslog.Debug, - log << "addBuffer: needs=" << iNumBlocks << " buffers for " << len << " bytes. Taken=" << m_iCount << "/" << m_iSize); + log << "addBuffer: needs=" << iNumBlocks << " buffers for " << len << " bytes. Taken=" << m_iCount.load() << "/" << m_iSize); // Retrieve current time before locking the mutex to be closer to packet submission event. const steady_clock::time_point tnow = steady_clock::now(); diff --git a/srtcore/core.cpp b/srtcore/core.cpp index ee76f2bcb..e321035d4 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -3125,7 +3125,7 @@ bool srt::CUDT::interpretGroup(const int32_t groupdata[], size_t data_size SRT_A { m_RejectReason = SRT_REJ_GROUP; LOGC(cnlog.Error, - log << CONID() << "HS/GROUP: incorrect group type value " << gtp << " (max is " << SRT_GTYPE_E_END << ")"); + log << CONID() << "HS/GROUP: incorrect group type value " << int(gtp) << " (max is " << int(SRT_GTYPE_E_END) << ")"); return false; } @@ -3299,8 +3299,8 @@ SRTSOCKET srt::CUDT::makeMePeerOf(SRTSOCKET peergroup, SRT_GROUP_TYPE gtp, uint3 if (gp->type() != gtp) { LOGC(gmlog.Error, - log << CONID() << "HS: GROUP TYPE COLLISION: peer group=$" << peergroup << " type " << gtp - << " agent group=$" << gp->id() << " type" << gp->type()); + log << CONID() << "HS: GROUP TYPE COLLISION: peer group=$" << peergroup << " type " << int(gtp) + << " agent group=$" << gp->id() << " type" << int(gp->type())); return -1; } diff --git a/srtcore/group.cpp b/srtcore/group.cpp index 0927d085a..5fea652d9 100644 --- a/srtcore/group.cpp +++ b/srtcore/group.cpp @@ -1023,7 +1023,7 @@ int CUDTGroup::send(const char* buf, int len, SRT_MSGCTRL& w_mc) switch (m_type) { default: - LOGC(gslog.Error, log << "CUDTGroup::send: not implemented for type #" << m_type); + LOGC(gslog.Error, log << "CUDTGroup::send: not implemented for type #" << int(m_type)); throw CUDTException(MJ_SETUP, MN_INVAL, 0); case SRT_GTYPE_BROADCAST: @@ -2189,9 +2189,10 @@ int CUDTGroup::recv(char* buf, int len, SRT_MSGCTRL& w_mc) { if (!m_bOpened || !m_bConnected) { + const char onoff[2] = {'-', '+'}; LOGC(grlog.Error, - log << boolalpha << "grp/recv: $" << id() << ": ABANDONING: opened=" << m_bOpened - << " connected=" << m_bConnected); + log << "grp/recv: $" << id() << ": ABANDONING: opened" << onoff[m_bOpened] + << " connected" << onoff[m_bConnected]); throw CUDTException(MJ_CONNECTION, MN_NOCONN, 0); } @@ -2249,7 +2250,7 @@ int CUDTGroup::recv(char* buf, int len, SRT_MSGCTRL& w_mc) { LOGC(grlog.Error, log << "grp/recv: $" << id() << ": @" << ps->m_SocketID << ": SEQUENCE DISCREPANCY: base=%" - << m_RcvBaseSeqNo << " vs pkt=%" << info.seqno << ", setting ESECFAIL"); + << m_RcvBaseSeqNo.load() << " vs pkt=%" << info.seqno << ", setting ESECFAIL"); ps->core().m_bBroken = true; broken.insert(ps); continue; From 5ae2a03e22efbf9ad7321ec8967910b695d3825f Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Sat, 25 May 2024 23:51:40 +0200 Subject: [PATCH 03/41] Updated sfmt.h with reimplementation fixes --- srtcore/sfmt.h | 82 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index 8eda16462..65632ad9a 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -190,6 +190,14 @@ class form_memory_buffer initial = reserved; } } + + void clear() + { + slices.clear(); + total = 0; + reserved = 0; + initial = 0; + } }; template @@ -291,22 +299,19 @@ form_memory_buffer<> fix_format(const char* fmt, } -template -struct Formatter -{ -}; - -#define SFMT_FORMAT_FIXER_TPL(tplarg, type, allowed, typed, deftype, warn)\ -template \ -struct Formatter \ +#define SFMT_FORMAT_FIXER(TYPE, ALLOWED, TYPED, DEFTYPE, WARN) \ +form_memory_buffer<> apply_format_fix(TYPE, const char* fmt) \ { \ - static form_memory_buffer<> fix(const char* fmt) \ - { \ - return internal::fix_format(fmt, allowed, typed, deftype, warn); \ - } \ + return fix_format(fmt, ALLOWED, TYPED, DEFTYPE, WARN); \ +} + +#define SFMT_FORMAT_FIXER_TPL(TPAR, TYPE, ALLOWED, TYPED, DEFTYPE, WARN) \ +template\ +form_memory_buffer<> apply_format_fix(TYPE, const char* fmt)\ +{\ + return fix_format(fmt, ALLOWED, TYPED, DEFTYPE, WARN); \ } -#define SFMT_FORMAT_FIXER(type, allowed, typed, deftype, warn) \ - SFMT_FORMAT_FIXER_TPL(, type, allowed, typed, deftype, warn) + // So, format in the format spec is: @@ -342,8 +347,8 @@ SFMT_FORMAT_FIXER(char, "", "c", "c", ""); SFMT_FORMAT_FIXER(std::string, "", "s", "s", ""); SFMT_FORMAT_FIXER(const char*, "", "s", "s", ""); SFMT_FORMAT_FIXER(char*, "", "s", "s", ""); -SFMT_FORMAT_FIXER_TPL(size_t N, const char[N], "", "s", "s", ""); -SFMT_FORMAT_FIXER_TPL(size_t N, char[N], "", "s", "s", ""); +SFMT_FORMAT_FIXER_TPL(size_t N, const char (&)[N], "", "s", "s", ""); +SFMT_FORMAT_FIXER_TPL(size_t N, char (&)[N], "", "s", "s", ""); SFMT_FORMAT_FIXER_TPL(class Type, Type*, "", "p", "p", ""); #undef SFMT_FORMAT_FIXER_TPL @@ -467,6 +472,11 @@ class obufstream obufstream() {} + void clear() + { + buffer.clear(); + } + obufstream& operator<<(const char* t) { size_t len = strlen(t); @@ -550,12 +560,27 @@ class obufstream } }; +namespace internal +{ +template +static inline size_t SNPrintfOne(char* buf, size_t bufsize, const char* fmt, const ValueType& val) +{ + return std::snprintf(buf, bufsize, fmt, val); +} + + +static inline size_t SNPrintfOne(char* buf, size_t bufsize, const char* fmt, const std::string& val) +{ + return std::snprintf(buf, bufsize, fmt, val.c_str()); +} +} + template inline internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) { using namespace internal; - form_memory_buffer<> fstr = Formatter::fix(fmtspec); + form_memory_buffer<> fstr = apply_format_fix(val, fmtspec); form_memory_buffer<> out; size_t bufsize = form_memory_buffer<>::INITIAL_SIZE; @@ -567,7 +592,7 @@ internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) // doesn't do it an doesn't use the NUL-termination. fstr.append('\0'); - size_t valsize = snprintf(buf, bufsize, fstr.get_first(), val); + size_t valsize = SNPrintfOne( buf, bufsize, fstr.get_first(), val); // Deemed impossible to happen, but still if (valsize == bufsize) @@ -590,7 +615,17 @@ internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) return out; } -template inline +namespace internal +{ +template inline +void write_default(Stream& s, const Value& v) +{ + s << sfmt(v, ""); +} +} + + +template std::string sfmts(const Value& val, const char* fmtspec = 0) { using namespace internal; @@ -613,15 +648,6 @@ std::string sfmts(const Value& val, const char* fmtspec = 0) return out; } -namespace internal -{ -template inline -void write_default(Stream& s, const Value& v) -{ - s << sfmt(v, ""); -} -} - // Semi-manipulator to add the end-of-line. const internal::form_memory_buffer<2> seol ("\n"); From 089dd51d3706474432a333b734f43b64fb6b384e Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Sun, 26 May 2024 00:35:01 +0200 Subject: [PATCH 04/41] Fixed heavy logging cases and atomics. Withdrawn changes for enums. Updated sfmt implementation --- srtcore/buffer_snd.cpp | 2 +- srtcore/congctl.cpp | 8 ++-- srtcore/core.cpp | 73 +++++++++++++++++++------------------ srtcore/group.cpp | 2 +- srtcore/queue.cpp | 2 +- srtcore/sfmt.h | 8 ++-- testing/testactivemedia.cpp | 3 +- testing/testactivemedia.hpp | 2 +- 8 files changed, 52 insertions(+), 48 deletions(-) diff --git a/srtcore/buffer_snd.cpp b/srtcore/buffer_snd.cpp index 998e080ab..901e829b6 100644 --- a/srtcore/buffer_snd.cpp +++ b/srtcore/buffer_snd.cpp @@ -242,7 +242,7 @@ int CSndBuffer::addBufferFromFile(fstream& ifs, int len) const int iNumBlocks = countNumPacketsRequired(len, iPktLen); HLOGC(bslog.Debug, - log << "addBufferFromFile: size=" << m_iCount << " reserved=" << m_iSize << " needs=" << iPktLen + log << "addBufferFromFile: size=" << m_iCount.load() << " reserved=" << m_iSize << " needs=" << iPktLen << " buffers for " << len << " bytes"); // dynamically increase sender buffer diff --git a/srtcore/congctl.cpp b/srtcore/congctl.cpp index b9265c046..bd4c9f162 100644 --- a/srtcore/congctl.cpp +++ b/srtcore/congctl.cpp @@ -87,7 +87,7 @@ class LiveCC: public SrtCongestionControlBase m_iMinNakInterval_us = 20000; //Minimum NAK Report Period (usec) m_iNakReportAccel = 2; //Default NAK Report Period (RTT) accelerator (send periodic NAK every RTT/2) - HLOGC(cclog.Debug, log << "Creating LiveCC: bw=" << m_llSndMaxBW << " avgplsize=" << m_zSndAvgPayloadSize); + HLOGC(cclog.Debug, log << "Creating LiveCC: bw=" << m_llSndMaxBW << " avgplsize=" << m_zSndAvgPayloadSize.load()); updatePktSndPeriod(); @@ -154,7 +154,7 @@ class LiveCC: public SrtCongestionControlBase // thread will pick up a "slightly outdated" average value from this // field - this is insignificant. m_zSndAvgPayloadSize = avg_iir<128, size_t>(m_zSndAvgPayloadSize, packet.getLength()); - HLOGC(cclog.Debug, log << "LiveCC: avg payload size updated: " << m_zSndAvgPayloadSize); + HLOGC(cclog.Debug, log << "LiveCC: avg payload size updated: " << m_zSndAvgPayloadSize.load()); } /// @brief On RTO event update an inter-packet send interval. @@ -179,7 +179,7 @@ class LiveCC: public SrtCongestionControlBase const double pktsize = (double) m_zSndAvgPayloadSize.load() + m_zHeaderSize; m_dPktSndPeriod = 1000 * 1000.0 * (pktsize / m_llSndMaxBW); HLOGC(cclog.Debug, log << "LiveCC: sending period updated: " << m_dPktSndPeriod - << " by avg pktsize=" << m_zSndAvgPayloadSize + << " by avg pktsize=" << m_zSndAvgPayloadSize.load() << ", bw=" << m_llSndMaxBW); } @@ -595,7 +595,7 @@ class FileCC : public SrtCongestionControlBase { m_dPktSndPeriod = m_dCWndSize / (m_parent->SRTT() + m_iRCInterval); HLOGC(cclog.Debug, log << "FileCC: CHKTIMER, SLOWSTART:OFF, sndperiod=" << m_dPktSndPeriod << "us AS wndsize/(RTT+RCIV) (wndsize=" - << setprecision(6) << m_dCWndSize << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); + << fmt::sfmt(m_dCWndSize, "06") << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); } } else diff --git a/srtcore/core.cpp b/srtcore/core.cpp index e321035d4..00ab9367b 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -425,7 +425,7 @@ void srt::CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen) const int status = m_config.set(optName, optval, optlen); if (status == -1) { - LOGC(aclog.Error, log << CONID() << "OPTION: #" << int(optName) << " UNKNOWN"); + LOGC(aclog.Error, log << CONID() << "OPTION: #" << optName << " UNKNOWN"); throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); } @@ -1036,7 +1036,7 @@ size_t srt::CUDT::fillSrtHandshake(uint32_t *aw_srtdata, size_t srtlen, int msgt if (srtlen < SRT_HS_E_SIZE) { LOGC(cnlog.Fatal, - log << CONID() << "IPE: fillSrtHandshake: buffer too small: " << srtlen << " (expected: " << int(SRT_HS_E_SIZE) << ")"); + log << CONID() << "IPE: fillSrtHandshake: buffer too small: " << srtlen << " (expected: " << SRT_HS_E_SIZE << ")"); return 0; } @@ -2343,8 +2343,8 @@ int srt::CUDT::processSrtMsg_HSRSP(const uint32_t *srtdata, size_t bytelen, uint m_uPeerSrtFlags = srtdata[SRT_HS_FLAGS]; HLOGC(cnlog.Debug, log << "HSRSP/rcv: Version: " << SrtVersionString(m_uPeerSrtVersion) - << " Flags: SND:" << setw(8) << setfill('0') << hex << m_uPeerSrtFlags - << setw(0) << " (" << SrtFlagString(m_uPeerSrtFlags) << ")"); + << " Flags: SND:" << sfmt(m_uPeerSrtFlags, "08x") + << " (" << SrtFlagString(m_uPeerSrtFlags) << ")"); // Basic version check if (m_uPeerSrtVersion < m_config.uMinimumPeerSrtVersion) { @@ -2528,7 +2528,7 @@ bool srt::CUDT::interpretSrtHandshake(const CHandShake& hs, m_RejectReason = SRT_REJ_ROGUE; LOGC(cnlog.Error, log << CONID() << "HS-ext HSREQ found but invalid size: " << bytelen - << " (expected: " << int(SRT_HS_E_SIZE) << ")"); + << " (expected: " << SRT_HS_E_SIZE << ")"); return false; // don't interpret } @@ -2554,7 +2554,7 @@ bool srt::CUDT::interpretSrtHandshake(const CHandShake& hs, m_RejectReason = SRT_REJ_ROGUE; LOGC(cnlog.Error, log << CONID() << "HS-ext HSRSP found but invalid size: " << bytelen - << " (expected: " << int(SRT_HS_E_SIZE) << ")"); + << " (expected: " << SRT_HS_E_SIZE << ")"); return false; // don't interpret } @@ -3125,7 +3125,7 @@ bool srt::CUDT::interpretGroup(const int32_t groupdata[], size_t data_size SRT_A { m_RejectReason = SRT_REJ_GROUP; LOGC(cnlog.Error, - log << CONID() << "HS/GROUP: incorrect group type value " << int(gtp) << " (max is " << int(SRT_GTYPE_E_END) << ")"); + log << CONID() << "HS/GROUP: incorrect group type value " << gtp << " (max is " << SRT_GTYPE_E_END << ")"); return false; } @@ -3299,8 +3299,8 @@ SRTSOCKET srt::CUDT::makeMePeerOf(SRTSOCKET peergroup, SRT_GROUP_TYPE gtp, uint3 if (gp->type() != gtp) { LOGC(gmlog.Error, - log << CONID() << "HS: GROUP TYPE COLLISION: peer group=$" << peergroup << " type " << int(gtp) - << " agent group=$" << gp->id() << " type" << int(gp->type())); + log << CONID() << "HS: GROUP TYPE COLLISION: peer group=$" << peergroup << " type " << gtp + << " agent group=$" << gp->id() << " type" << gp->type()); return -1; } @@ -3883,7 +3883,7 @@ void srt::CUDT::startConnect(const sockaddr_any& serv_addr, int32_t forced_isn) HLOGC(cnlog.Debug, log << CONID() << "startConnect: END. Parameters: mss=" << m_config.iMSS << " max-cwnd-size=" << m_CongCtl->cgWindowMaxSize() << " cwnd-size=" << m_CongCtl->cgWindowSize() - << " rtt=" << m_iSRTT << " bw=" << m_iBandwidth); + << " rtt=" << m_iSRTT.load() << " bw=" << m_iBandwidth.load()); } // Asynchronous connection @@ -4022,7 +4022,7 @@ void srt::CUDT::sendRendezvousRejection(const sockaddr_any& serv_addr, CPacket& r_rsppkt.setLength(size); HLOGC(cnlog.Debug, log << CONID() << "sendRendezvousRejection: using code=" << m_ConnReq.m_iReqType - << " for reject reason code " << m_RejectReason << " (" << srt_rejectreason_str(m_RejectReason) << ")"); + << " for reject reason code " << m_RejectReason.load() << " (" << srt_rejectreason_str(m_RejectReason) << ")"); setPacketTS(r_rsppkt, steady_clock::now()); m_pSndQueue->sendto(serv_addr, r_rsppkt, m_SourceAddr); @@ -5471,7 +5471,7 @@ void * srt::CUDT::tsbpd(void* param) HLOGC(tslog.Debug, log << self->CONID() << "tsbpd: DROPSEQ: up to seqno %" << CSeqNo::decseq(info.seqno) << " (" << iDropCnt << " packets) playable at " << FormatTime(info.tsbpd_time) << " delayed " - << (timediff_us / 1000) << "." << std::setw(3) << std::setfill('0') << (timediff_us % 1000) << " ms"); + << (timediff_us / 1000) << "." << sfmt(timediff_us % 1000, "03") << " ms"); #endif string why; if (self->frequentLogAllowed(FREQLOGFA_RCV_DROPPED, tnow, (why))) @@ -6114,8 +6114,9 @@ SRT_REJECT_REASON srt::CUDT::setupCC() HLOGC(rslog.Debug, log << CONID() << "setupCC: setting parameters: mss=" << m_config.iMSS << " maxCWNDSize/FlowWindowSize=" - << m_iFlowWindowSize << " rcvrate=" << m_iDeliveryRate << "p/s (" << m_iByteDeliveryRate << "B/S)" - << " rtt=" << m_iSRTT << " bw=" << m_iBandwidth); + << m_iFlowWindowSize.load() << " rcvrate=" << m_iDeliveryRate.load() + << "p/s (" << m_iByteDeliveryRate.load() << "B/S)" + << " rtt=" << m_iSRTT.load() << " bw=" << m_iBandwidth.load()); if (!updateCC(TEV_INIT, EventVariant(TEV_INIT_RESET))) { @@ -7115,7 +7116,7 @@ int srt::CUDT::receiveMessage(char* data, int len, SRT_MSGCTRL& w_mctrl, int by_ // After signaling the tsbpd for ready data, report the bandwidth. #if ENABLE_HEAVY_LOGGING double bw = Bps2Mbps(int64_t(m_iBandwidth) * m_iMaxSRTPayloadSize ); - HLOGC(arlog.Debug, log << CONID() << "CURRENT BANDWIDTH: " << bw << "Mbps (" << m_iBandwidth << " buffers per second)"); + HLOGC(arlog.Debug, log << CONID() << "CURRENT BANDWIDTH: " << bw << "Mbps (" << m_iBandwidth.load() << " buffers per second)"); #endif } return res; @@ -7777,8 +7778,7 @@ bool srt::CUDT::updateCC(ETransmissionEvent evt, const EventVariant arg) #if ENABLE_HEAVY_LOGGING HLOGC(rslog.Debug, log << CONID() << "updateCC: updated values from congctl: interval=" << FormatDuration(m_tdSendInterval) - << " (cfg:" << m_CongCtl->pktSndPeriod_us() << "us) cgwindow=" - << std::setprecision(3) << cgwindow); + << " (cfg:" << m_CongCtl->pktSndPeriod_us() << "us) cgwindow=" << sfmt(cgwindow, ".3")); #endif } @@ -8425,8 +8425,9 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ const bool isLiteAck = ctrlpkt.getLength() == (size_t)SEND_LITE_ACK; HLOGC(inlog.Debug, - log << CONID() << "ACK covers: " << m_iSndLastDataAck << " - " << ackdata_seqno << " [ACK=" << m_iSndLastAck - << "]" << (isLiteAck ? "[LITE]" : "[FULL]")); + log << CONID() << "ACK covers: " << m_iSndLastDataAck.load() << " - " + << ackdata_seqno << " [ACK=" << m_iSndLastAck.load() << "]" + << (isLiteAck ? "[LITE]" : "[FULL]")); updateSndLossListOnACK(ackdata_seqno); @@ -8497,8 +8498,9 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ { m_pSndQueue->m_pSndUList->update(this, CSndUList::DONT_RESCHEDULE); HLOGC(gglog.Debug, - log << CONID() << "processCtrlAck: could reschedule SND. iFlowWindowSize " << m_iFlowWindowSize - << " SPAN " << getFlightSpan() << " ackdataseqno %" << ackdata_seqno); + log << CONID() << "processCtrlAck: could reschedule SND. iFlowWindowSize " + << m_iFlowWindowSize.load() << " SPAN " << getFlightSpan() + << " ackdataseqno %" << ackdata_seqno); } } @@ -8823,7 +8825,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) if (CSeqNo::seqcmp(losslist_hi, m_iSndLastAck) >= 0) { HLOGC(inlog.Debug, log << CONID() << "LOSSREPORT: adding " - << m_iSndLastAck << "[ACK] - " << losslist_hi << " to loss list"); + << m_iSndLastAck.load() << "[ACK] - " << losslist_hi << " to loss list"); num = m_pSndLossList->insert(m_iSndLastAck, losslist_hi); dropreq_hi = CSeqNo::decseq(m_iSndLastAck); IF_HEAVY_LOGGING(drop_type = "partially"); @@ -8839,8 +8841,9 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) // - finally give up rexmit request as per TLPKTDROP (DROPREQ should make // TSBPD wake up should it still wait for new packets to get ACK-ed) HLOGC(inlog.Debug, - log << CONID() << "LOSSREPORT: " << drop_type << " IGNORED with SndLastAck=%" << m_iSndLastAck - << ": %" << losslist_lo << "-" << dropreq_hi << " - sending DROPREQ"); + log << CONID() << "LOSSREPORT: " << drop_type << " IGNORED with SndLastAck=%" + << m_iSndLastAck.load() << ": %" << losslist_lo << "-" << dropreq_hi + << " - sending DROPREQ"); sendCtrl(UMSG_DROPREQ, &no_msgno, seqpair, sizeof(seqpair)); } @@ -8880,7 +8883,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) int32_t seqpair[2] = { losslist[i], losslist[i] }; const int32_t no_msgno = 0; // We don't know. HLOGC(inlog.Debug, - log << CONID() << "LOSSREPORT: IGNORED with SndLastAck=%" << m_iSndLastAck << ": %" << losslist[i] + log << CONID() << "LOSSREPORT: IGNORED with SndLastAck=%" << m_iSndLastAck.load() << ": %" << losslist[i] << " - sending DROPREQ"); sendCtrl(UMSG_DROPREQ, &no_msgno, seqpair, sizeof(seqpair)); } @@ -9364,7 +9367,7 @@ int srt::CUDT::packLostData(CPacket& w_packet) { HLOGC(qrlog.Debug, log << CONID() << "REXMIT: ignoring seqno " << w_packet.seqno() << ", last rexmit " << (is_zero(tsLastRexmit) ? "never" : FormatTime(tsLastRexmit)) - << " RTT=" << m_iSRTT << " RTTVar=" << m_iRTTVar + << " RTT=" << m_iSRTT.load() << " RTTVar=" << m_iRTTVar.load() << " now=" << FormatTime(time_now)); continue; } @@ -9676,8 +9679,8 @@ bool srt::CUDT::packData(CPacket& w_packet, steady_clock::time_point& w_nexttime #if ENABLE_HEAVY_LOGGING // Required because of referring to MessageFlagStr() HLOGC(qslog.Debug, - log << CONID() << "packData: " << reason << " packet seq=" << w_packet.seqno() << " (ACK=" << m_iSndLastAck - << " ACKDATA=" << m_iSndLastDataAck << " MSG/FLAGS: " << w_packet.MessageFlagStr() << ")"); + log << CONID() << "packData: " << reason << " packet seq=" << w_packet.seqno() << " (ACK=" << m_iSndLastAck.load() + << " ACKDATA=" << m_iSndLastDataAck.load() << " MSG/FLAGS: " << w_packet.MessageFlagStr() << ")"); #endif // Fix keepalive @@ -9757,8 +9760,8 @@ bool srt::CUDT::packUniqueData(CPacket& w_packet) if (cwnd <= flightspan) { HLOGC(qslog.Debug, - log << CONID() << "packUniqueData: CONGESTED: cwnd=min(" << m_iFlowWindowSize << "," << m_iCongestionWindow - << ")=" << cwnd << " seqlen=(" << m_iSndLastAck << "-" << m_iSndCurrSeqNo.load() << ")=" << flightspan); + log << CONID() << "packUniqueData: CONGESTED: cwnd=min(" << m_iFlowWindowSize.load() << "," << m_iCongestionWindow.load() + << ")=" << cwnd << " seqlen=(" << m_iSndLastAck.load() << "-" << m_iSndCurrSeqNo.load() << ")=" << flightspan); return false; } @@ -10013,9 +10016,9 @@ int srt::CUDT::checkLazySpawnTsbPdThread() HLOGP(qrlog.Debug, "Spawning Socket TSBPD thread"); #if ENABLE_HEAVY_LOGGING - std::ostringstream tns1, tns2; + fmt::obufstream tns1, tns2; // Take the last 2 ciphers from the socket ID. - tns1 << setfill('0') << setw(2) << m_SocketID; + tns1 << sfmt(m_SocketID, "02"); std::string s = tns1.str(); tns2 << "SRT:TsbPd:@" << s.substr(s.size()-2, 2); const string thname = tns2.str(); @@ -11199,7 +11202,7 @@ int srt::CUDT::processConnectRequest(const sockaddr_any& addr, CPacket& packet) if (!accepted_hs) { HLOGC(cnlog.Debug, - log << CONID() << "processConnectRequest: version/type mismatch. Sending REJECT code:" << m_RejectReason + log << CONID() << "processConnectRequest: version/type mismatch. Sending REJECT code:" << m_RejectReason.load() << " MSG: " << srt_rejectreason_str(m_RejectReason)); // mismatch, reject the request hs.m_iReqType = URQFailure(m_RejectReason); @@ -11231,7 +11234,7 @@ int srt::CUDT::processConnectRequest(const sockaddr_any& addr, CPacket& packet) if (result == -1) { hs.m_iReqType = URQFailure(error); - LOGC(cnlog.Warn, log << "processConnectRequest: rsp(REJECT): " << int(hs.m_iReqType) << " - " << srt_rejectreason_str(error)); + LOGC(cnlog.Warn, log << "processConnectRequest: rsp(REJECT): " << hs.m_iReqType << " - " << srt_rejectreason_str(error)); } // The `acpu` not NULL means connection exists, the `result` should be 0. It is not checked here though. @@ -11335,7 +11338,7 @@ int srt::CUDT::processConnectRequest(const sockaddr_any& addr, CPacket& packet) } } } - LOGC(cnlog.Debug, log << CONID() << "listen ret: " << int(hs.m_iReqType) << " - " << RequestTypeStr(hs.m_iReqType)); + LOGC(cnlog.Debug, log << CONID() << "listen ret: " << hs.m_iReqType << " - " << RequestTypeStr(hs.m_iReqType)); return RejectReasonForURQ(hs.m_iReqType); } diff --git a/srtcore/group.cpp b/srtcore/group.cpp index 5fea652d9..332b1657d 100644 --- a/srtcore/group.cpp +++ b/srtcore/group.cpp @@ -1023,7 +1023,7 @@ int CUDTGroup::send(const char* buf, int len, SRT_MSGCTRL& w_mc) switch (m_type) { default: - LOGC(gslog.Error, log << "CUDTGroup::send: not implemented for type #" << int(m_type)); + LOGC(gslog.Error, log << "CUDTGroup::send: not implemented for type #" << m_type); throw CUDTException(MJ_SETUP, MN_INVAL, 0); case SRT_GTYPE_BROADCAST: diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp index 98999a81f..aefcea001 100644 --- a/srtcore/queue.cpp +++ b/srtcore/queue.cpp @@ -139,7 +139,7 @@ srt::CUnitQueue::CQEntry* srt::CUnitQueue::allocateEntry(const int iNumUnits, co int srt::CUnitQueue::increase_() { const int numUnits = m_iBlockSize; - HLOGC(qrlog.Debug, log << "CUnitQueue::increase: Capacity" << capacity() << " + " << numUnits << " new units, " << m_iNumTaken << " in use."); + HLOGC(qrlog.Debug, log << "CUnitQueue::increase: Capacity" << capacity() << " + " << numUnits << " new units, " << m_iNumTaken.load() << " in use."); CQEntry* tempq = allocateEntry(numUnits, m_iMSS); if (tempq == NULL) diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index 65632ad9a..f635a1020 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -300,14 +300,14 @@ form_memory_buffer<> fix_format(const char* fmt, #define SFMT_FORMAT_FIXER(TYPE, ALLOWED, TYPED, DEFTYPE, WARN) \ -form_memory_buffer<> apply_format_fix(TYPE, const char* fmt) \ +inline form_memory_buffer<> apply_format_fix(TYPE, const char* fmt) \ { \ return fix_format(fmt, ALLOWED, TYPED, DEFTYPE, WARN); \ } #define SFMT_FORMAT_FIXER_TPL(TPAR, TYPE, ALLOWED, TYPED, DEFTYPE, WARN) \ template\ -form_memory_buffer<> apply_format_fix(TYPE, const char* fmt)\ +inline form_memory_buffer<> apply_format_fix(TYPE, const char* fmt)\ {\ return fix_format(fmt, ALLOWED, TYPED, DEFTYPE, WARN); \ } @@ -592,7 +592,7 @@ internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) // doesn't do it an doesn't use the NUL-termination. fstr.append('\0'); - size_t valsize = SNPrintfOne( buf, bufsize, fstr.get_first(), val); + size_t valsize = SNPrintfOne(buf, bufsize, fstr.get_first(), val); // Deemed impossible to happen, but still if (valsize == bufsize) @@ -601,7 +601,7 @@ internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) // Just try again with one extra size, if this won't // suffice, just add <...> at the end. buf = out.expose(bufsize); - valsize = snprintf(buf, bufsize, fstr.get_first(), val); + valsize = SNPrintfOne(buf, bufsize, fstr.get_first(), val); if (valsize == bufsize) { char* end = buf + bufsize - 6; diff --git a/testing/testactivemedia.cpp b/testing/testactivemedia.cpp index 96344f0b2..d89cc0211 100644 --- a/testing/testactivemedia.cpp +++ b/testing/testactivemedia.cpp @@ -82,9 +82,10 @@ void TargetMedium::Runner() return; } + const char* yesno[2] = {"no", "yes"}; bool gotsomething = ready.wait_for(lg, chrono::seconds(1), [this] { return !running || !buffer.empty(); } ); LOGP(applog.Debug, "TargetMedium(", typeid(*med).name(), "): [", val.payload.size(), "] BUFFER update (timeout:", - boolalpha, gotsomething, " running: ", running, ")"); + yesno[!gotsomething], " running: ", running.load(), ")"); if (::transmit_int_state || !running || !med || med->Broken()) { LOGP(applog.Debug, "TargetMedium(", typeid(*med).name(), "): buffer empty, medium ", diff --git a/testing/testactivemedia.hpp b/testing/testactivemedia.hpp index 011dcbfe7..67782edbd 100644 --- a/testing/testactivemedia.hpp +++ b/testing/testactivemedia.hpp @@ -151,7 +151,7 @@ struct TargetMedium: Medium { LOGP(applog.Debug, "TargetMedium::Schedule LOCK ... "); std::lock_guard lg(buffer_lock); - LOGP(applog.Debug, "TargetMedium::Schedule LOCKED - checking: running=", running, " interrupt=", ::transmit_int_state); + LOGP(applog.Debug, "TargetMedium::Schedule LOCKED - checking: running=", running.load(), " interrupt=", ::transmit_int_state.load()); if (!running || ::transmit_int_state) { LOGP(applog.Debug, "TargetMedium::Schedule: not running, discarding packet"); From e37d37dab19c7c530397a55ab59b27fd788f71e6 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Sun, 26 May 2024 15:03:30 +0200 Subject: [PATCH 05/41] Provided a special version for atomic. Withdrawn unnecessary changes --- srtcore/buffer_snd.cpp | 6 +-- srtcore/congctl.cpp | 8 ++-- srtcore/core.cpp | 91 ++++++++++++++++++------------------- srtcore/group.cpp | 2 +- srtcore/logging.h | 65 ++++++++++++++++++-------- srtcore/queue.cpp | 2 +- srtcore/socketconfig.cpp | 10 ++-- testing/testactivemedia.cpp | 2 +- testing/testactivemedia.hpp | 2 +- 9 files changed, 107 insertions(+), 81 deletions(-) diff --git a/srtcore/buffer_snd.cpp b/srtcore/buffer_snd.cpp index 901e829b6..ef1bc498c 100644 --- a/srtcore/buffer_snd.cpp +++ b/srtcore/buffer_snd.cpp @@ -141,7 +141,7 @@ void CSndBuffer::addBuffer(const char* data, int len, SRT_MSGCTRL& w_mctrl) const int iNumBlocks = countNumPacketsRequired(len, iPktLen); HLOGC(bslog.Debug, - log << "addBuffer: needs=" << iNumBlocks << " buffers for " << len << " bytes. Taken=" << m_iCount.load() << "/" << m_iSize); + log << "addBuffer: needs=" << iNumBlocks << " buffers for " << len << " bytes. Taken=" << m_iCount << "/" << m_iSize); // Retrieve current time before locking the mutex to be closer to packet submission event. const steady_clock::time_point tnow = steady_clock::now(); @@ -242,7 +242,7 @@ int CSndBuffer::addBufferFromFile(fstream& ifs, int len) const int iNumBlocks = countNumPacketsRequired(len, iPktLen); HLOGC(bslog.Debug, - log << "addBufferFromFile: size=" << m_iCount.load() << " reserved=" << m_iSize << " needs=" << iPktLen + log << "addBufferFromFile: size=" << m_iCount << " reserved=" << m_iSize << " needs=" << iPktLen << " buffers for " << len << " bytes"); // dynamically increase sender buffer @@ -393,7 +393,7 @@ int32_t CSndBuffer::getMsgNoAt(const int offset) { // Prevent accessing the last "marker" block LOGC(bslog.Error, - log << "CSndBuffer::getMsgNoAt: IPE: offset=" << offset << " not found, max offset=" << m_iCount.load()); + log << "CSndBuffer::getMsgNoAt: IPE: offset=" << offset << " not found, max offset=" << m_iCount); return SRT_MSGNO_CONTROL; } diff --git a/srtcore/congctl.cpp b/srtcore/congctl.cpp index bd4c9f162..0f6edb15b 100644 --- a/srtcore/congctl.cpp +++ b/srtcore/congctl.cpp @@ -87,7 +87,7 @@ class LiveCC: public SrtCongestionControlBase m_iMinNakInterval_us = 20000; //Minimum NAK Report Period (usec) m_iNakReportAccel = 2; //Default NAK Report Period (RTT) accelerator (send periodic NAK every RTT/2) - HLOGC(cclog.Debug, log << "Creating LiveCC: bw=" << m_llSndMaxBW << " avgplsize=" << m_zSndAvgPayloadSize.load()); + HLOGC(cclog.Debug, log << "Creating LiveCC: bw=" << m_llSndMaxBW << " avgplsize=" << m_zSndAvgPayloadSize); updatePktSndPeriod(); @@ -154,7 +154,7 @@ class LiveCC: public SrtCongestionControlBase // thread will pick up a "slightly outdated" average value from this // field - this is insignificant. m_zSndAvgPayloadSize = avg_iir<128, size_t>(m_zSndAvgPayloadSize, packet.getLength()); - HLOGC(cclog.Debug, log << "LiveCC: avg payload size updated: " << m_zSndAvgPayloadSize.load()); + HLOGC(cclog.Debug, log << "LiveCC: avg payload size updated: " << m_zSndAvgPayloadSize); } /// @brief On RTO event update an inter-packet send interval. @@ -179,7 +179,7 @@ class LiveCC: public SrtCongestionControlBase const double pktsize = (double) m_zSndAvgPayloadSize.load() + m_zHeaderSize; m_dPktSndPeriod = 1000 * 1000.0 * (pktsize / m_llSndMaxBW); HLOGC(cclog.Debug, log << "LiveCC: sending period updated: " << m_dPktSndPeriod - << " by avg pktsize=" << m_zSndAvgPayloadSize.load() + << " by avg pktsize=" << m_zSndAvgPayloadSize << ", bw=" << m_llSndMaxBW); } @@ -595,7 +595,7 @@ class FileCC : public SrtCongestionControlBase { m_dPktSndPeriod = m_dCWndSize / (m_parent->SRTT() + m_iRCInterval); HLOGC(cclog.Debug, log << "FileCC: CHKTIMER, SLOWSTART:OFF, sndperiod=" << m_dPktSndPeriod << "us AS wndsize/(RTT+RCIV) (wndsize=" - << fmt::sfmt(m_dCWndSize, "06") << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); + << fmt::sfmt(m_dCWndSize, ".6") << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); } } else diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 00ab9367b..f87692caa 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -88,11 +88,13 @@ using namespace std; using namespace srt; using namespace srt::sync; using namespace srt_logging; -using namespace fmt; +using fmt::sfmt; const SRTSOCKET UDT::INVALID_SOCK = srt::CUDT::INVALID_SOCK; const int UDT::ERROR = srt::CUDT::ERROR; +static const char onoff[2] = {'-', '+'}; + //#define SRT_CMD_HSREQ 1 /* SRT Handshake Request (sender) */ #define SRT_CMD_HSREQ_MINSZ 8 /* Minumum Compatible (1.x.x) packet size (bytes) */ #define SRT_CMD_HSREQ_SZ 12 /* Current version packet size */ @@ -1772,7 +1774,6 @@ bool srt::CUDT::createSrtHandshake( if (!m_pCryptoControl && (srtkm_cmd == SRT_CMD_KMREQ || srtkm_cmd == SRT_CMD_KMRSP)) { m_RejectReason = SRT_REJ_IPE; - static const char onoff[2] = {'-', '+'}; LOGC(cnlog.Error, log << CONID() << "createSrtHandshake: IPE: need to send KM, but CryptoControl does not exist." << " Socket state: " @@ -3457,7 +3458,7 @@ void srt::CUDT::synchronizeWithGroup(CUDTGroup* gp) { HLOGC(gmlog.Debug, log << CONID() << "synchronizeWithGroup: DERIVED ISN: RCV=%" << m_iRcvLastAck << " -> %" << rcv_isn - << " (shift by " << CSeqNo::seqcmp(rcv_isn, m_iRcvLastAck) << ") SND=%" << m_iSndLastAck.load() + << " (shift by " << CSeqNo::seqcmp(rcv_isn, m_iRcvLastAck) << ") SND=%" << m_iSndLastAck << " -> %" << snd_isn << " (shift by " << CSeqNo::seqcmp(snd_isn, m_iSndLastAck) << ")"); setInitialRcvSeq(rcv_isn); setInitialSndSeq(snd_isn); @@ -3466,7 +3467,7 @@ void srt::CUDT::synchronizeWithGroup(CUDTGroup* gp) { HLOGC(gmlog.Debug, log << CONID() << "synchronizeWithGroup: DEFINED ISN: RCV=%" << m_iRcvLastAck << " SND=%" - << m_iSndLastAck.load()); + << m_iSndLastAck); } } #endif @@ -3883,7 +3884,7 @@ void srt::CUDT::startConnect(const sockaddr_any& serv_addr, int32_t forced_isn) HLOGC(cnlog.Debug, log << CONID() << "startConnect: END. Parameters: mss=" << m_config.iMSS << " max-cwnd-size=" << m_CongCtl->cgWindowMaxSize() << " cwnd-size=" << m_CongCtl->cgWindowSize() - << " rtt=" << m_iSRTT.load() << " bw=" << m_iBandwidth.load()); + << " rtt=" << m_iSRTT << " bw=" << m_iBandwidth); } // Asynchronous connection @@ -4022,7 +4023,7 @@ void srt::CUDT::sendRendezvousRejection(const sockaddr_any& serv_addr, CPacket& r_rsppkt.setLength(size); HLOGC(cnlog.Debug, log << CONID() << "sendRendezvousRejection: using code=" << m_ConnReq.m_iReqType - << " for reject reason code " << m_RejectReason.load() << " (" << srt_rejectreason_str(m_RejectReason) << ")"); + << " for reject reason code " << m_RejectReason << " (" << srt_rejectreason_str(m_RejectReason) << ")"); setPacketTS(r_rsppkt, steady_clock::now()); m_pSndQueue->sendto(serv_addr, r_rsppkt, m_SourceAddr); @@ -4104,7 +4105,6 @@ EConnectStatus srt::CUDT::craftKmResponse(uint32_t* aw_kmdata, size_t& w_kmdatas // m_pCryptoControl can be NULL if the socket has been closed already. See issue #2231. if (!m_pCryptoControl) { - static const char onoff[2] = {'-', '+'}; m_RejectReason = SRT_REJ_IPE; LOGC(cnlog.Error, log << CONID() << "IPE: craftKmResponse needs to send KM, but CryptoControl does not exist." @@ -6114,9 +6114,8 @@ SRT_REJECT_REASON srt::CUDT::setupCC() HLOGC(rslog.Debug, log << CONID() << "setupCC: setting parameters: mss=" << m_config.iMSS << " maxCWNDSize/FlowWindowSize=" - << m_iFlowWindowSize.load() << " rcvrate=" << m_iDeliveryRate.load() - << "p/s (" << m_iByteDeliveryRate.load() << "B/S)" - << " rtt=" << m_iSRTT.load() << " bw=" << m_iBandwidth.load()); + << m_iFlowWindowSize << " rcvrate=" << m_iDeliveryRate << "p/s (" << m_iByteDeliveryRate << "B/S)" + << " rtt=" << m_iSRTT << " bw=" << m_iBandwidth); if (!updateCC(TEV_INIT, EventVariant(TEV_INIT_RESET))) { @@ -6585,7 +6584,7 @@ int srt::CUDT::sndDropTooLate() } HLOGC(qslog.Debug, - log << CONID() << "SND-DROP: %(" << realack << "-" << m_iSndCurrSeqNo.load() << ") n=" << dpkts << "pkt " << dbytes + log << CONID() << "SND-DROP: %(" << realack << "-" << m_iSndCurrSeqNo << ") n=" << dpkts << "pkt " << dbytes << "B, span=" << buffdelay_ms << " ms, FIRST #" << first_msgno); #if ENABLE_BONDING @@ -7116,7 +7115,7 @@ int srt::CUDT::receiveMessage(char* data, int len, SRT_MSGCTRL& w_mctrl, int by_ // After signaling the tsbpd for ready data, report the bandwidth. #if ENABLE_HEAVY_LOGGING double bw = Bps2Mbps(int64_t(m_iBandwidth) * m_iMaxSRTPayloadSize ); - HLOGC(arlog.Debug, log << CONID() << "CURRENT BANDWIDTH: " << bw << "Mbps (" << m_iBandwidth.load() << " buffers per second)"); + HLOGC(arlog.Debug, log << CONID() << "CURRENT BANDWIDTH: " << bw << "Mbps (" << m_iBandwidth << " buffers per second)"); #endif } return res; @@ -8425,9 +8424,8 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ const bool isLiteAck = ctrlpkt.getLength() == (size_t)SEND_LITE_ACK; HLOGC(inlog.Debug, - log << CONID() << "ACK covers: " << m_iSndLastDataAck.load() << " - " - << ackdata_seqno << " [ACK=" << m_iSndLastAck.load() << "]" - << (isLiteAck ? "[LITE]" : "[FULL]")); + log << CONID() << "ACK covers: " << m_iSndLastDataAck << " - " << ackdata_seqno << " [ACK=" << m_iSndLastAck + << "]" << (isLiteAck ? "[LITE]" : "[FULL]")); updateSndLossListOnACK(ackdata_seqno); @@ -8477,7 +8475,7 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ // this should not happen: attack or bug LOGC(gglog.Error, log << CONID() << "ATTACK/IPE: incoming ack seq " << ackdata_seqno << " exceeds current " - << m_iSndCurrSeqNo.load() << " by " << (CSeqNo::seqoff(m_iSndCurrSeqNo, ackdata_seqno) - 1) << "!"); + << m_iSndCurrSeqNo << " by " << (CSeqNo::seqoff(m_iSndCurrSeqNo, ackdata_seqno) - 1) << "!"); m_bBroken = true; m_iBrokenCounter = 0; return; @@ -8498,9 +8496,8 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ { m_pSndQueue->m_pSndUList->update(this, CSndUList::DONT_RESCHEDULE); HLOGC(gglog.Debug, - log << CONID() << "processCtrlAck: could reschedule SND. iFlowWindowSize " - << m_iFlowWindowSize.load() << " SPAN " << getFlightSpan() - << " ackdataseqno %" << ackdata_seqno); + log << CONID() << "processCtrlAck: could reschedule SND. iFlowWindowSize " << m_iFlowWindowSize + << " SPAN " << getFlightSpan() << " ackdataseqno %" << ackdata_seqno); } } @@ -8680,14 +8677,14 @@ void srt::CUDT::processCtrlAckAck(const CPacket& ctrlpkt, const time_point& tsAr LOGC(inlog.Note, log << CONID() << "ACKACK out of order, skipping RTT calculation " << "(ACK number: " << ctrlpkt.getAckSeqNo() << ", last ACK sent: " << m_iAckSeqNo - << ", RTT (EWMA): " << m_iSRTT.load() << ")"); + << ", RTT (EWMA): " << m_iSRTT << ")"); return; } LOGC(inlog.Error, log << CONID() << "ACK record not found, can't estimate RTT " << "(ACK number: " << ctrlpkt.getAckSeqNo() << ", last ACK sent: " << m_iAckSeqNo - << ", RTT (EWMA): " << m_iSRTT.load() << ")"); + << ", RTT (EWMA): " << m_iSRTT << ")"); return; } @@ -8790,7 +8787,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) // LO must not be greater than HI. // HI must not be greater than the most recent sent seq. LOGC(inlog.Warn, log << CONID() << "rcv LOSSREPORT rng " << losslist_lo << " - " << losslist_hi - << " with last sent " << m_iSndCurrSeqNo.load() << " - DISCARDING"); + << " with last sent " << m_iSndCurrSeqNo << " - DISCARDING"); secure = false; wrong_loss = losslist_hi; break; @@ -8825,7 +8822,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) if (CSeqNo::seqcmp(losslist_hi, m_iSndLastAck) >= 0) { HLOGC(inlog.Debug, log << CONID() << "LOSSREPORT: adding " - << m_iSndLastAck.load() << "[ACK] - " << losslist_hi << " to loss list"); + << m_iSndLastAck << "[ACK] - " << losslist_hi << " to loss list"); num = m_pSndLossList->insert(m_iSndLastAck, losslist_hi); dropreq_hi = CSeqNo::decseq(m_iSndLastAck); IF_HEAVY_LOGGING(drop_type = "partially"); @@ -8841,9 +8838,8 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) // - finally give up rexmit request as per TLPKTDROP (DROPREQ should make // TSBPD wake up should it still wait for new packets to get ACK-ed) HLOGC(inlog.Debug, - log << CONID() << "LOSSREPORT: " << drop_type << " IGNORED with SndLastAck=%" - << m_iSndLastAck.load() << ": %" << losslist_lo << "-" << dropreq_hi - << " - sending DROPREQ"); + log << CONID() << "LOSSREPORT: " << drop_type << " IGNORED with SndLastAck=%" << m_iSndLastAck + << ": %" << losslist_lo << "-" << dropreq_hi << " - sending DROPREQ"); sendCtrl(UMSG_DROPREQ, &no_msgno, seqpair, sizeof(seqpair)); } @@ -8860,7 +8856,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) if (CSeqNo::seqcmp(losslist[i], m_iSndCurrSeqNo) > 0) { LOGC(inlog.Warn, log << CONID() << "rcv LOSSREPORT pkt %" << losslist[i] - << " with last sent %" << m_iSndCurrSeqNo.load() << " - DISCARDING"); + << " with last sent %" << m_iSndCurrSeqNo << " - DISCARDING"); // loss_seq must not be greater than the most recent sent seq secure = false; wrong_loss = losslist[i]; @@ -8883,7 +8879,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) int32_t seqpair[2] = { losslist[i], losslist[i] }; const int32_t no_msgno = 0; // We don't know. HLOGC(inlog.Debug, - log << CONID() << "LOSSREPORT: IGNORED with SndLastAck=%" << m_iSndLastAck.load() << ": %" << losslist[i] + log << CONID() << "LOSSREPORT: IGNORED with SndLastAck=%" << m_iSndLastAck << ": %" << losslist[i] << " - sending DROPREQ"); sendCtrl(UMSG_DROPREQ, &no_msgno, seqpair, sizeof(seqpair)); } @@ -8896,7 +8892,7 @@ void srt::CUDT::processCtrlLossReport(const CPacket& ctrlpkt) if (!secure) { LOGC(inlog.Warn, - log << CONID() << "out-of-band LOSSREPORT received; BUG or ATTACK - last sent %" << m_iSndCurrSeqNo.load() + log << CONID() << "out-of-band LOSSREPORT received; BUG or ATTACK - last sent %" << m_iSndCurrSeqNo << " vs loss %" << wrong_loss); // this should not happen: attack or bug m_bBroken = true; @@ -9088,7 +9084,7 @@ void srt::CUDT::processCtrlDropReq(const CPacket& ctrlpkt) else { HLOGC(inlog.Debug, log << CONID() << "DROPREQ: dropping %" - << dropdata[0] << "-" << dropdata[1] << " current %" << m_iRcvCurrSeqNo.load()); + << dropdata[0] << "-" << dropdata[1] << " current %" << m_iRcvCurrSeqNo); } } @@ -9336,7 +9332,7 @@ int srt::CUDT::packLostData(CPacket& w_packet) // was completely ignored. LOGC(qrlog.Error, log << CONID() << "IPE/EPE: packLostData: LOST packet negative offset: seqoff(seqno() " - << w_packet.seqno() << ", m_iSndLastDataAck " << m_iSndLastDataAck.load() << ")=" << offset + << w_packet.seqno() << ", m_iSndLastDataAck " << m_iSndLastDataAck << ")=" << offset << ". Continue, request DROP"); // No matter whether this is right or not (maybe the attack case should be @@ -9367,7 +9363,7 @@ int srt::CUDT::packLostData(CPacket& w_packet) { HLOGC(qrlog.Debug, log << CONID() << "REXMIT: ignoring seqno " << w_packet.seqno() << ", last rexmit " << (is_zero(tsLastRexmit) ? "never" : FormatTime(tsLastRexmit)) - << " RTT=" << m_iSRTT.load() << " RTTVar=" << m_iRTTVar.load() + << " RTT=" << m_iSRTT << " RTTVar=" << m_iRTTVar << " now=" << FormatTime(time_now)); continue; } @@ -9679,8 +9675,8 @@ bool srt::CUDT::packData(CPacket& w_packet, steady_clock::time_point& w_nexttime #if ENABLE_HEAVY_LOGGING // Required because of referring to MessageFlagStr() HLOGC(qslog.Debug, - log << CONID() << "packData: " << reason << " packet seq=" << w_packet.seqno() << " (ACK=" << m_iSndLastAck.load() - << " ACKDATA=" << m_iSndLastDataAck.load() << " MSG/FLAGS: " << w_packet.MessageFlagStr() << ")"); + log << CONID() << "packData: " << reason << " packet seq=" << w_packet.seqno() << " (ACK=" << m_iSndLastAck + << " ACKDATA=" << m_iSndLastDataAck << " MSG/FLAGS: " << w_packet.MessageFlagStr() << ")"); #endif // Fix keepalive @@ -9760,8 +9756,8 @@ bool srt::CUDT::packUniqueData(CPacket& w_packet) if (cwnd <= flightspan) { HLOGC(qslog.Debug, - log << CONID() << "packUniqueData: CONGESTED: cwnd=min(" << m_iFlowWindowSize.load() << "," << m_iCongestionWindow.load() - << ")=" << cwnd << " seqlen=(" << m_iSndLastAck.load() << "-" << m_iSndCurrSeqNo.load() << ")=" << flightspan); + log << CONID() << "packUniqueData: CONGESTED: cwnd=min(" << m_iFlowWindowSize << "," << m_iCongestionWindow + << ")=" << cwnd << " seqlen=(" << m_iSndLastAck << "-" << m_iSndCurrSeqNo << ")=" << flightspan); return false; } @@ -9777,7 +9773,7 @@ bool srt::CUDT::packUniqueData(CPacket& w_packet) { // Some packets were skipped due to TTL expiry. m_iSndCurrSeqNo = CSeqNo::incseq(m_iSndCurrSeqNo, pktskipseqno); - HLOGC(qslog.Debug, log << "packUniqueData: reading skipped " << pktskipseqno << " seq up to %" << m_iSndCurrSeqNo.load() + HLOGC(qslog.Debug, log << "packUniqueData: reading skipped " << pktskipseqno << " seq up to %" << m_iSndCurrSeqNo << " due to TTL expiry"); } @@ -9981,7 +9977,7 @@ bool srt::CUDT::overrideSndSeqNo(int32_t seq) if (diff < 0 || diff > CSeqNo::m_iSeqNoTH) { LOGC(gslog.Error, log << CONID() << "IPE: Overriding with seq %" << seq << " DISCREPANCY against current %" - << m_iSndCurrSeqNo.load() << " and next sched %" << m_iSndNextSeqNo.load() << " - diff=" << diff); + << m_iSndCurrSeqNo << " and next sched %" << m_iSndNextSeqNo << " - diff=" << diff); return false; } @@ -9998,7 +9994,7 @@ bool srt::CUDT::overrideSndSeqNo(int32_t seq) // not yet sent. HLOGC(gslog.Debug, - log << CONID() << "overrideSndSeqNo: sched-seq=" << m_iSndNextSeqNo.load() << " send-seq=" << m_iSndCurrSeqNo.load() + log << CONID() << "overrideSndSeqNo: sched-seq=" << m_iSndNextSeqNo << " send-seq=" << m_iSndCurrSeqNo << " (unchanged)"); return true; } @@ -10016,12 +10012,11 @@ int srt::CUDT::checkLazySpawnTsbPdThread() HLOGP(qrlog.Debug, "Spawning Socket TSBPD thread"); #if ENABLE_HEAVY_LOGGING - fmt::obufstream tns1, tns2; + fmt::obufstream buf; // Take the last 2 ciphers from the socket ID. - tns1 << sfmt(m_SocketID, "02"); - std::string s = tns1.str(); - tns2 << "SRT:TsbPd:@" << s.substr(s.size()-2, 2); - const string thname = tns2.str(); + string s = fmt::sfmts(m_SocketID, "02"); + buf << "SRT:TsbPd:@" << s.substr(s.size()-2, 2); + const string thname = buf.str(); #else const string thname = "SRT:TsbPd"; #endif @@ -10121,7 +10116,7 @@ int srt::CUDT::handleSocketPacketReception(const vector& incoming, bool& "SEQUENCE DISCREPANCY. BREAKING CONNECTION." " %" << rpkt.seqno() << " buffer=(%" << bufseq - << ":%" << m_iRcvCurrSeqNo.load() // -1 = size to last index + << ":%" << m_iRcvCurrSeqNo // -1 = size to last index << "+%" << CSeqNo::incseq(bufseq, int(m_pRcvBuffer->capacity()) - 1) << "), " << (m_pRcvBuffer->capacity() - bufidx + 1) << " past max. Reception no longer possible. REQUESTING TO CLOSE."); @@ -10241,7 +10236,7 @@ int srt::CUDT::handleSocketPacketReception(const vector& incoming, bool& bufinfo << " BUF.s=" << m_pRcvBuffer->capacity() << " avail=" << (int(m_pRcvBuffer->capacity()) - ackidx) << " buffer=(%" << bufseq - << ":%" << m_iRcvCurrSeqNo.load() // -1 = size to last index + << ":%" << m_iRcvCurrSeqNo // -1 = size to last index << "+%" << CSeqNo::incseq(bufseq, int(m_pRcvBuffer->capacity()) - 1) << ")"; } @@ -10739,7 +10734,7 @@ void srt::CUDT::updateIdleLinkFrom(CUDT* source) { // Reject the change because that would shift the reception pointer backwards. HLOGC(grlog.Debug, log << "grp: NOT updating rcv-seq in @" << m_SocketID - << ": backward setting rejected: %" << m_iRcvCurrSeqNo.load() + << ": backward setting rejected: %" << m_iRcvCurrSeqNo << " -> %" << new_last_rcv); return; } @@ -11202,7 +11197,7 @@ int srt::CUDT::processConnectRequest(const sockaddr_any& addr, CPacket& packet) if (!accepted_hs) { HLOGC(cnlog.Debug, - log << CONID() << "processConnectRequest: version/type mismatch. Sending REJECT code:" << m_RejectReason.load() + log << CONID() << "processConnectRequest: version/type mismatch. Sending REJECT code:" << m_RejectReason << " MSG: " << srt_rejectreason_str(m_RejectReason)); // mismatch, reject the request hs.m_iReqType = URQFailure(m_RejectReason); diff --git a/srtcore/group.cpp b/srtcore/group.cpp index 332b1657d..286d65de5 100644 --- a/srtcore/group.cpp +++ b/srtcore/group.cpp @@ -2250,7 +2250,7 @@ int CUDTGroup::recv(char* buf, int len, SRT_MSGCTRL& w_mc) { LOGC(grlog.Error, log << "grp/recv: $" << id() << ": @" << ps->m_SocketID << ": SEQUENCE DISCREPANCY: base=%" - << m_RcvBaseSeqNo.load() << " vs pkt=%" << info.seqno << ", setting ESECFAIL"); + << m_RcvBaseSeqNo << " vs pkt=%" << info.seqno << ", setting ESECFAIL"); ps->core().m_bBroken = true; broken.insert(ps); continue; diff --git a/srtcore/logging.h b/srtcore/logging.h index 0917af9ac..0953a397d 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -337,6 +337,43 @@ struct LogDispatcher::Proxy return *this; } + // Special case for atomics, as passing them to snprintf() call + // requires unpacking the real underlying value. + template + Proxy& operator<<(const srt::sync::atomic& arg) + { + if ( that_enabled ) + { + os << arg.load(); + } + return *this; + } + + +#if HAVE_CXX11 + + void dispatch() {} + + template + void dispatch(const Arg1& a1, const Args&... others) + { + *this << a1; + dispatch(others...); + } + + // Special dispatching for atomics must be provided here. + // By some reason, "*this << a1" expression gets dispatched + // to the general version of operator<<, not the overload for + // atomic. Even though the compiler shows Arg1 type as atomic. + template + void dispatch(const std::atomic& a1, const Args&... others) + { + *this << a1.load(); + dispatch(others...); + } + +#endif + ~Proxy() { if ( that_enabled ) @@ -445,19 +482,19 @@ inline void PrintArgs(fmt::obufstream& serr, Arg1&& arg1, Args&&... args) PrintArgs(serr, args...); } +// Add exceptional handling for sync::atomic +template +inline void PrintArgs(fmt::obufstream& serr, const srt::sync::atomic& arg1, Args&&... args) +{ + serr << arg1.load(); + PrintArgs(serr, args...); +} + template inline void LogDispatcher::PrintLogLine(const char* file SRT_ATR_UNUSED, int line SRT_ATR_UNUSED, const std::string& area SRT_ATR_UNUSED, Args&&... args SRT_ATR_UNUSED) { #ifdef ENABLE_LOGGING - fmt::obufstream serr; - CreateLogLinePrefix(serr); - PrintArgs(serr, args...); - - if ( !isset(SRT_LOGF_DISABLE_EOL) ) - serr << fmt::seol; - - // Not sure, but it wasn't ever used. - SendLogLine(file, line, area, serr.str()); + Proxy(*this).dispatch(args...); #endif } @@ -467,15 +504,7 @@ template inline void LogDispatcher::PrintLogLine(const char* file SRT_ATR_UNUSED, int line SRT_ATR_UNUSED, const std::string& area SRT_ATR_UNUSED, const Arg& arg SRT_ATR_UNUSED) { #ifdef ENABLE_LOGGING - fmt::obufstream serr; - CreateLogLinePrefix(serr); - serr << arg; - - if ( !isset(SRT_LOGF_DISABLE_EOL) ) - serr << fmt::seol; - - // Not sure, but it wasn't ever used. - SendLogLine(file, line, area, serr.str()); + Proxy(*this) << arg; #endif } diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp index aefcea001..98999a81f 100644 --- a/srtcore/queue.cpp +++ b/srtcore/queue.cpp @@ -139,7 +139,7 @@ srt::CUnitQueue::CQEntry* srt::CUnitQueue::allocateEntry(const int iNumUnits, co int srt::CUnitQueue::increase_() { const int numUnits = m_iBlockSize; - HLOGC(qrlog.Debug, log << "CUnitQueue::increase: Capacity" << capacity() << " + " << numUnits << " new units, " << m_iNumTaken.load() << " in use."); + HLOGC(qrlog.Debug, log << "CUnitQueue::increase: Capacity" << capacity() << " + " << numUnits << " new units, " << m_iNumTaken << " in use."); CQEntry* tempq = allocateEntry(numUnits, m_iMSS); if (tempq == NULL) diff --git a/srtcore/socketconfig.cpp b/srtcore/socketconfig.cpp index 9c5a9513e..cec4845b4 100644 --- a/srtcore/socketconfig.cpp +++ b/srtcore/socketconfig.cpp @@ -52,6 +52,8 @@ written by #include "srt.h" #include "socketconfig.h" +using fmt::sfmt; + namespace srt { int RcvBufferSizeOptionToValue(int val, int flightflag, int mss) @@ -744,8 +746,8 @@ struct CSrtConfigSetter { co.uKmPreAnnouncePkt = (km_refresh - 1) / 2; LOGC(aclog.Warn, - log << "SRTO_KMREFRESHRATE=0x" << fmt::sfmt(km_refresh, "x") << ": setting SRTO_KMPREANNOUNCE=0x" - << fmt::sfmt(co.uKmPreAnnouncePkt, "x")); + log << "SRTO_KMREFRESHRATE=0x" << sfmt(km_refresh, "x") << ": setting SRTO_KMPREANNOUNCE=0x" + << sfmt(co.uKmPreAnnouncePkt, "x")); } } }; @@ -770,8 +772,8 @@ struct CSrtConfigSetter if (km_preanno > (kmref - 1) / 2) { LOGC(aclog.Error, - log << "SRTO_KMPREANNOUNCE=0x" << fmt::sfmt(km_preanno, "x") - << " exceeds KmRefresh/2, 0x" << fmt::sfmt((kmref - 1) / 2) + log << "SRTO_KMPREANNOUNCE=0x" << sfmt(km_preanno, "x") + << " exceeds KmRefresh/2, 0x" << sfmt((kmref - 1) / 2, "x") << " - OPTION REJECTED."); throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); } diff --git a/testing/testactivemedia.cpp b/testing/testactivemedia.cpp index d89cc0211..332a9fd6f 100644 --- a/testing/testactivemedia.cpp +++ b/testing/testactivemedia.cpp @@ -85,7 +85,7 @@ void TargetMedium::Runner() const char* yesno[2] = {"no", "yes"}; bool gotsomething = ready.wait_for(lg, chrono::seconds(1), [this] { return !running || !buffer.empty(); } ); LOGP(applog.Debug, "TargetMedium(", typeid(*med).name(), "): [", val.payload.size(), "] BUFFER update (timeout:", - yesno[!gotsomething], " running: ", running.load(), ")"); + yesno[!gotsomething], " running: ", running, ")"); if (::transmit_int_state || !running || !med || med->Broken()) { LOGP(applog.Debug, "TargetMedium(", typeid(*med).name(), "): buffer empty, medium ", diff --git a/testing/testactivemedia.hpp b/testing/testactivemedia.hpp index 67782edbd..011dcbfe7 100644 --- a/testing/testactivemedia.hpp +++ b/testing/testactivemedia.hpp @@ -151,7 +151,7 @@ struct TargetMedium: Medium { LOGP(applog.Debug, "TargetMedium::Schedule LOCK ... "); std::lock_guard lg(buffer_lock); - LOGP(applog.Debug, "TargetMedium::Schedule LOCKED - checking: running=", running.load(), " interrupt=", ::transmit_int_state.load()); + LOGP(applog.Debug, "TargetMedium::Schedule LOCKED - checking: running=", running, " interrupt=", ::transmit_int_state); if (!running || ::transmit_int_state) { LOGP(applog.Debug, "TargetMedium::Schedule: not running, discarding packet"); From 6ce84feace50ac1fb2990759df99f3978524b8f0 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Sun, 26 May 2024 16:04:54 +0200 Subject: [PATCH 06/41] Changed more formatting usage to sfmt --- srtcore/api.cpp | 4 ++-- srtcore/queue.cpp | 4 ++-- srtcore/sfmt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++ srtcore/sync.cpp | 22 +++++++++++++------ srtcore/sync.h | 6 +++-- srtcore/utilities.h | 22 ++++++++++++++----- 6 files changed, 93 insertions(+), 18 deletions(-) diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 56c581fec..62bbd787b 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -231,7 +231,7 @@ string srt::CUDTUnited::CONID(SRTSOCKET sock) if (sock == 0) return ""; - std::ostringstream os; + fmt::obufstream os; os << "@" << sock << ":"; return os.str(); } @@ -3240,7 +3240,7 @@ bool srt::CUDTUnited::updateListenerMux(CUDTSocket* s, const CUDTSocket* ls) CMultiplexer& m = i->second; #if ENABLE_HEAVY_LOGGING - ostringstream that_muxer; + fmt::obufstream that_muxer; that_muxer << "id=" << m.m_iID << " port=" << m.m_iPort << " ip=" << (m.m_iIPversion == AF_INET ? "v4" : "v6"); #endif diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp index 98999a81f..78de6a6b9 100644 --- a/srtcore/queue.cpp +++ b/srtcore/queue.cpp @@ -1078,8 +1078,8 @@ bool srt::CRendezvousQueue::qualifyToHandle(EReadStatus rst, else { HLOGC(cnlog.Debug, - log << "RID: socket @" << i->m_iID << " still active (remaining " << std::fixed - << (count_microseconds(i->m_tsTTL - tsNow) / 1000000.0) << "s of TTL)..."); + log << "RID: socket @" << i->m_iID << " still active (remaining " + << fmt::sfmt(count_microseconds(i->m_tsTTL - tsNow) / 1000000.0, "f") << "s of TTL)..."); } const steady_clock::time_point tsLastReq = i->m_pUDT->m_tsLastReqTime; diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index f635a1020..367926bce 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -10,6 +10,9 @@ // for FILE type from stdio. It has nothing to do with the rest of the {fmt} // library, except that it reuses the namespace. +#ifndef INC_FMT_SFMT_H +#define INC_FMT_SFMT_H + #include #include #include @@ -490,6 +493,19 @@ class obufstream return *this; } + // For unusual manipulation, usually to add NUL termination. + // NOTE: you must make sure that you won't use the extended + // buffers if the intention was to get a string. + void append(char c) + { + buffer.append(c); + } + + const char* bufptr() const + { + return buffer.get_first(); + } + template obufstream& operator<<(const internal::form_memory_buffer& b) { @@ -558,6 +574,41 @@ class obufstream std::copy(data, data + i->size(), std::back_inserter(out)); } } + + template + size_t copy_to(OutputContainer& out, size_t maxsize) const + { + using namespace internal; + size_t avail = maxsize; + if (avail < buffer.first_size()) + { + std::copy(buffer.get_first(), buffer.get_first() + avail, + std::back_inserter(out)); + return maxsize; + } + + std::copy(buffer.get_first(), buffer.get_first() + buffer.first_size(), + std::back_inserter(out)); + + avail -= buffer.first_size(); + + for (form_memory_buffer<>::slices_t::const_iterator i = buffer.get_slices().begin(); + i != buffer.get_slices().end(); ++i) + { + // Would be tempting to move the blocks, but C++03 doesn't feature moving. + const char* data = &(*i)[0]; + + if (avail < i->size()) + { + std::copy(data, data + avail, std::back_inserter(out)); + return maxsize; + } + std::copy(data, data + i->size(), std::back_inserter(out)); + avail -= i->size(); + } + + return maxsize - avail; + } }; namespace internal @@ -662,3 +713,5 @@ inline ostdiostream& operator<<(ostdiostream& sout, const os_flush_manip&) } + +#endif diff --git a/srtcore/sync.cpp b/srtcore/sync.cpp index a7cebb909..e4e511fb5 100644 --- a/srtcore/sync.cpp +++ b/srtcore/sync.cpp @@ -50,13 +50,21 @@ std::string FormatTime(const steady_clock::time_point& timestamp) const uint64_t hours = total_sec / (60 * 60) - days * 24; const uint64_t minutes = total_sec / 60 - (days * 24 * 60) - hours * 60; const uint64_t seconds = total_sec - (days * 24 * 60 * 60) - hours * 60 * 60 - minutes * 60; - ostringstream out; + + // Temporary solution. Need to find some better handling + // of dynamic width and precision. + fmt::obufstream dfmts; + dfmts << "0" << decimals; + dfmts.append('\0'); // form_memory_buffer doesn't use NUL-termination. + const char* decimal_fmt = dfmts.bufptr(); + + fmt::obufstream out; if (days) out << days << "D "; - out << setfill('0') << setw(2) << hours << ":" - << setfill('0') << setw(2) << minutes << ":" - << setfill('0') << setw(2) << seconds << "." - << setfill('0') << setw(decimals) << (timestamp - seconds_from(total_sec)).time_since_epoch().count() << " [STDY]"; + out << fmt::sfmt(hours, "02") << ":" + << fmt::sfmt(minutes, "02") << ":" + << fmt::sfmt(seconds, "02") << "." + << fmt::sfmt((timestamp - seconds_from(total_sec)).time_since_epoch().count(), decimal_fmt) << " [STDY]"; return out.str(); } @@ -72,8 +80,8 @@ std::string FormatTimeSys(const steady_clock::time_point& timestamp) char tmp_buf[512]; strftime(tmp_buf, 512, "%X.", &tm); - ostringstream out; - out << tmp_buf << setfill('0') << setw(6) << (count_microseconds(timestamp.time_since_epoch()) % 1000000) << " [SYST]"; + fmt::obufstream out; + out << tmp_buf << fmt::sfmt(count_microseconds(timestamp.time_since_epoch()) % 1000000, "06") << " [SYST]"; return out.str(); } diff --git a/srtcore/sync.h b/srtcore/sync.h index fb6d56432..627f7eac5 100644 --- a/srtcore/sync.h +++ b/srtcore/sync.h @@ -55,7 +55,7 @@ #include "srt.h" #include "utilities.h" #include "srt_attr_defs.h" - +#include "sfmt.h" namespace srt { @@ -775,7 +775,9 @@ struct DurationUnitName template inline std::string FormatDuration(const steady_clock::duration& dur) { - return Sprint(std::fixed, DurationUnitName::count(dur)) + DurationUnitName::name(); + fmt::obufstream out; + out << fmt::sfmt(DurationUnitName::count(dur), "f") << DurationUnitName::name(); + return out.str(); } inline std::string FormatDuration(const steady_clock::duration& dur) diff --git a/srtcore/utilities.h b/srtcore/utilities.h index 1786cf0ae..ef5e41d81 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -34,7 +34,6 @@ written by #include #include #include -#include #include #if HAVE_CXX11 @@ -46,6 +45,8 @@ written by #include #include +#include "sfmt.h" + // -------------- UTILITIES ------------------------ // --- ENDIAN --- @@ -981,6 +982,19 @@ inline std::string FormatBinaryString(const uint8_t* bytes, size_t size) if ( size == 0 ) return ""; + using namespace fmt; + + obufstream os; + + os << sfmt(bytes[0], "02X"); + for (size_t i = 1; i < size; ++i) + { + os << sfmt(bytes[i], "02X"); + } + return os.str(); + + /* OLD VERSION + //char buf[256]; using namespace std; @@ -1008,6 +1022,7 @@ inline std::string FormatBinaryString(const uint8_t* bytes, size_t size) os << int(bytes[i]); } return os.str(); + */ } @@ -1171,10 +1186,7 @@ inline std::string BufferStamp(const char* mem, size_t size) } // Convert to hex string - ostringstream os; - os << hex << uppercase << setfill('0') << setw(8) << sum; - - return os.str(); + return fmt::sfmts(sum, "08X"); } template From 8126c49f91c1cd675fda6a76824d238b6e5d126b Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Sun, 26 May 2024 20:42:30 +0200 Subject: [PATCH 07/41] Removed ostringstream from utilities --- srtcore/utilities.h | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/srtcore/utilities.h b/srtcore/utilities.h index ef5e41d81..697e43e08 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -485,7 +485,7 @@ class FixedArray void throw_invalid_index(int i) const { - std::stringstream ss; + fmt::obufstream ss; ss << "Index " << i << "out of range"; throw std::runtime_error(ss.str()); } @@ -587,7 +587,7 @@ inline Stream& Print(Stream& sout, Arg1&& arg1, Args&&... args) template inline std::string Sprint(Args&&... args) { - std::ostringstream sout; + fmt::obufstream sout; Print(sout, args...); return sout.str(); } @@ -598,19 +598,32 @@ inline std::string Sprint(Args&&... args) template using UniquePtr = std::unique_ptr; -template inline -std::string Printable(const Container& in, Value /*pseudoargument*/, Args&&... args) +template inline +std::string Printable(const Container& in, Value /*pseudoargument*/, const char* fmt = 0) { using namespace srt_pair_op; - std::ostringstream os; - Print(os, args...); + fmt::obufstream os; os << "[ "; for (auto i: in) - os << Value(i) << " "; + os << fmt::sfmt(i, fmt) << " "; os << "]"; return os.str(); } +// Separate version for pairs, used for std::map +template inline +std::string Printable(const Container& in, std::pair/*pseudoargument*/, const char* fmtk = 0, const char* fmtv = 0) +{ + using namespace srt_pair_op; + fmt::obufstream os; + os << "[ "; + for (auto i: in) + os << fmt::sfmt(i.first, fmtk) << ":" << fmt::sfmt(i.second, fmtv) << " "; + os << "]"; + return os.str(); +} + + template inline std::string Printable(const Container& in) { @@ -694,16 +707,14 @@ class UniquePtr: public std::auto_ptr template inline std::string Sprint(const Arg1& arg) { - std::ostringstream sout; - sout << arg; - return sout.str(); + return fmt::sfmts(arg); } // Ok, let it be 2-arg, in case when a manipulator is needed template inline std::string Sprint(const Arg1& arg1, const Arg2& arg2) { - std::ostringstream sout; + fmt::obufstream sout; sout << arg1 << arg2; return sout.str(); } @@ -713,7 +724,7 @@ std::string Printable(const Container& in) { using namespace srt_pair_op; typedef typename Container::value_type Value; - std::ostringstream os; + fmt::obufstream os; os << "[ "; for (typename Container::const_iterator i = in.begin(); i != in.end(); ++i) os << Value(*i) << " "; @@ -759,7 +770,7 @@ std::string PrintableMod(const Container& in, const std::string& prefix) { using namespace srt_pair_op; typedef typename Container::value_type Value; - std::ostringstream os; + fmt::obufstream os; os << "[ "; for (typename Container::const_iterator y = in.begin(); y != in.end(); ++y) os << prefix << Value(*y) << " "; From 216c1ed489b654f8c760f1cabec936e9f6ca74bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Mon, 27 May 2024 08:06:12 +0200 Subject: [PATCH 08/41] Removed ostringstream use. Fixed C++03 problem with Ensure declaration --- apps/logsupport.cpp | 2 +- apps/uriparser.cpp | 2 +- srtcore/sfmt.h | 6 +++++- srtcore/utilities.h | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/logsupport.cpp b/apps/logsupport.cpp index fbd70c47e..7192f4596 100644 --- a/apps/logsupport.cpp +++ b/apps/logsupport.cpp @@ -173,7 +173,7 @@ set SrtParseLogFA(string fa, set* punknown) void ParseLogFASpec(const vector& speclist, string& w_on, string& w_off) { - std::ostringstream son, soff; + fmt::obufstream son, soff; for (auto& s: speclist) { diff --git a/apps/uriparser.cpp b/apps/uriparser.cpp index 6b8c80713..47e8f6a7f 100644 --- a/apps/uriparser.cpp +++ b/apps/uriparser.cpp @@ -64,7 +64,7 @@ string UriParser::makeUri() prefix = m_proto + "://"; } - std::ostringstream out; + fmt::obufstream out; out << prefix << m_host; if ((m_port == "" || m_port == "0") && m_expect == EXPECT_FILE) diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index 367926bce..61bbd8914 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -242,7 +242,11 @@ struct Ensure template struct Ensure { - typename AnyType::wrong_condition v = AnyType::wrong_condition; + static void CheckIfCharsetNonEmpty() + { + typename AnyType::wrong_condition v = AnyType::wrong_condition; + (void)v; + } }; template inline diff --git a/srtcore/utilities.h b/srtcore/utilities.h index 697e43e08..b82beb76f 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -531,8 +531,8 @@ struct explicit_t // but this function has a different definition for C++11 and C++03. namespace srt_pair_op { - template - std::ostream& operator<<(std::ostream& s, const std::pair& v) + template + Stream& operator<<(Stream& s, const std::pair& v) { s << "{" << v.first << " " << v.second << "}"; return s; From d8cebcdd4b5588f8e60e0a160562c66a5b216f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Mon, 27 May 2024 09:58:04 +0200 Subject: [PATCH 09/41] Cleared out warn-errors for logging-off version --- srtcore/group.cpp | 7 ++++--- srtcore/queue.h | 4 ++++ testing/testactivemedia.cpp | 8 ++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/srtcore/group.cpp b/srtcore/group.cpp index 286d65de5..0333f7408 100644 --- a/srtcore/group.cpp +++ b/srtcore/group.cpp @@ -15,6 +15,8 @@ extern const int32_t SRT_DEF_VERSION; namespace srt { +static inline char fmt_onoff(bool val) { return val ? '+' : '-'; } + int32_t CUDTGroup::s_tokenGen = 0; // [[using locked(this->m_GroupLock)]]; @@ -2189,10 +2191,9 @@ int CUDTGroup::recv(char* buf, int len, SRT_MSGCTRL& w_mc) { if (!m_bOpened || !m_bConnected) { - const char onoff[2] = {'-', '+'}; LOGC(grlog.Error, - log << "grp/recv: $" << id() << ": ABANDONING: opened" << onoff[m_bOpened] - << " connected" << onoff[m_bConnected]); + log << "grp/recv: $" << id() << ": ABANDONING: opened" << fmt_onoff(m_bOpened) + << " connected" << fmt_onoff(m_bConnected)); throw CUDTException(MJ_CONNECTION, MN_NOCONN, 0); } diff --git a/srtcore/queue.h b/srtcore/queue.h index dd68a7721..055671e95 100644 --- a/srtcore/queue.h +++ b/srtcore/queue.h @@ -592,6 +592,10 @@ struct CMultiplexer , m_pRcvQueue(NULL) , m_pChannel(NULL) , m_pTimer(NULL) + , m_iPort(0) + , m_iIPversion(0) + , m_iRefCount(1) + , m_iID(-1) { } diff --git a/testing/testactivemedia.cpp b/testing/testactivemedia.cpp index 332a9fd6f..9f2f03c98 100644 --- a/testing/testactivemedia.cpp +++ b/testing/testactivemedia.cpp @@ -3,6 +3,11 @@ using namespace std; +#if ENABLE_LOGGING +namespace { +const char* fmt_yesno(bool b) { return b ? "yes" : "no"; } +} +#endif void SourceMedium::Runner() { @@ -82,10 +87,9 @@ void TargetMedium::Runner() return; } - const char* yesno[2] = {"no", "yes"}; bool gotsomething = ready.wait_for(lg, chrono::seconds(1), [this] { return !running || !buffer.empty(); } ); LOGP(applog.Debug, "TargetMedium(", typeid(*med).name(), "): [", val.payload.size(), "] BUFFER update (timeout:", - yesno[!gotsomething], " running: ", running, ")"); + fmt_yesno(!gotsomething), " running: ", running, ")"); if (::transmit_int_state || !running || !med || med->Broken()) { LOGP(applog.Debug, "TargetMedium(", typeid(*med).name(), "): buffer empty, medium ", From 4e39fd7a628a5acae905c4e121fb34dd569d8059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Mon, 27 May 2024 12:01:24 +0200 Subject: [PATCH 10/41] Moved Printable out of C++11-dependent section (args... no longer needed) --- srtcore/utilities.h | 83 +++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/srtcore/utilities.h b/srtcore/utilities.h index b82beb76f..83405b44c 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -598,40 +598,6 @@ inline std::string Sprint(Args&&... args) template using UniquePtr = std::unique_ptr; -template inline -std::string Printable(const Container& in, Value /*pseudoargument*/, const char* fmt = 0) -{ - using namespace srt_pair_op; - fmt::obufstream os; - os << "[ "; - for (auto i: in) - os << fmt::sfmt(i, fmt) << " "; - os << "]"; - return os.str(); -} - -// Separate version for pairs, used for std::map -template inline -std::string Printable(const Container& in, std::pair/*pseudoargument*/, const char* fmtk = 0, const char* fmtv = 0) -{ - using namespace srt_pair_op; - fmt::obufstream os; - os << "[ "; - for (auto i: in) - os << fmt::sfmt(i.first, fmtk) << ":" << fmt::sfmt(i.second, fmtv) << " "; - os << "]"; - return os.str(); -} - - -template inline -std::string Printable(const Container& in) -{ - using namespace srt_pair_op; - using Value = typename Container::value_type; - return Printable(in, Value()); -} - template auto map_get(Map& m, const Key& key, typename Map::mapped_type def = typename Map::mapped_type()) -> typename Map::mapped_type { @@ -719,20 +685,6 @@ inline std::string Sprint(const Arg1& arg1, const Arg2& arg2) return sout.str(); } -template inline -std::string Printable(const Container& in) -{ - using namespace srt_pair_op; - typedef typename Container::value_type Value; - fmt::obufstream os; - os << "[ "; - for (typename Container::const_iterator i = in.begin(); i != in.end(); ++i) - os << Value(*i) << " "; - os << "]"; - - return os.str(); -} - template typename Map::mapped_type map_get(Map& m, const Key& key, typename Map::mapped_type def = typename Map::mapped_type()) { @@ -763,6 +715,41 @@ typename Map::mapped_type const* map_getp(const Map& m, const Key& key) #endif +template inline +std::string Printable(const Container& in, Value /*pseudoargument*/, const char* fmt = 0) +{ + fmt::obufstream os; + os << "[ "; + typedef typename Container::const_iterator it_t; + for (it_t i = in.begin(); i != in.end(); ++i) + os << fmt::sfmt(*i, fmt) << " "; + os << "]"; + return os.str(); +} + +// Separate version for pairs, used for std::map +template inline +std::string Printable(const Container& in, std::pair/*pseudoargument*/, const char* fmtk = 0, const char* fmtv = 0) +{ + using namespace srt_pair_op; + fmt::obufstream os; + os << "[ "; + typedef typename Container::const_iterator it_t; + for (it_t i = in.begin(); i != in.end(); ++i) + os << fmt::sfmt(i->first, fmtk) << ":" << fmt::sfmt(i->second, fmtv) << " "; + os << "]"; + return os.str(); +} + + +template inline +std::string Printable(const Container& in) +{ + using namespace srt_pair_op; + typedef typename Container::value_type Value; + return Printable(in, Value()); +} + // Printable with prefix added for every element. // Useful when printing a container of sockets or sequence numbers. template inline From 51997464083b02e3f77dec378aaa90fd23116e19 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Mon, 27 May 2024 23:10:09 +0200 Subject: [PATCH 11/41] Added extra version of snprintf for old Windows --- srtcore/sfmt.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index 61bbd8914..cb64b90f5 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -617,18 +617,24 @@ class obufstream namespace internal { +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define FMT_SYM_SNPRINTF _snprintf +#define FMT_SIZE_SNPRINTF(bufsize) (bufsize-1) +#else +#define FMT_SYM_SNPRINTF std::snprintf +#define FMT_SIZE_SNPRINTF(bufsize) bufsize +#endif + template static inline size_t SNPrintfOne(char* buf, size_t bufsize, const char* fmt, const ValueType& val) -{ - return std::snprintf(buf, bufsize, fmt, val); -} - +{ return FMT_SYM_SNPRINTF (buf, FMT_SIZE_SNPRINTF(bufsize), fmt, val); } static inline size_t SNPrintfOne(char* buf, size_t bufsize, const char* fmt, const std::string& val) -{ - return std::snprintf(buf, bufsize, fmt, val.c_str()); -} +{ return FMT_SYM_SNPRINTF(buf, FMT_SIZE_SNPRINTF(bufsize), fmt, val.c_str()); } + } +#undef FMT_SYM_SNPRINTF +#undef FMT_SIZE_SNPRINTF template inline internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) From 4843143322967f65987ef16a3d97c6dc1346cd20 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Tue, 28 May 2024 09:27:37 +0200 Subject: [PATCH 12/41] Fixed the use of std::atomic --- srtcore/logging.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srtcore/logging.h b/srtcore/logging.h index 0953a397d..94cda07be 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -366,7 +366,7 @@ struct LogDispatcher::Proxy // to the general version of operator<<, not the overload for // atomic. Even though the compiler shows Arg1 type as atomic. template - void dispatch(const std::atomic& a1, const Args&... others) + void dispatch(const srt::sync::atomic& a1, const Args&... others) { *this << a1.load(); dispatch(others...); From 1a0eca49e3d9dd9d92daf91720919c618d5342b0 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Tue, 28 May 2024 12:46:22 +0200 Subject: [PATCH 13/41] Fixed the right atomic type used with logging. Fixed some reported shadowed local variables --- testing/srt-test-relay.cpp | 6 +++--- testing/testactivemedia.cpp | 16 ++++++++++++++++ testing/testactivemedia.hpp | 20 ++------------------ testing/testmedia.cpp | 29 ++++++++++++++--------------- testing/testmedia.hpp | 5 +++-- testing/testmediabase.hpp | 4 ++-- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/testing/srt-test-relay.cpp b/testing/srt-test-relay.cpp index 45d657128..18e6acf3d 100755 --- a/testing/srt-test-relay.cpp +++ b/testing/srt-test-relay.cpp @@ -367,9 +367,9 @@ SrtMainLoop::SrtMainLoop(const string& srt_uri, bool input_echoback, const strin Verb() << "SRT set up as input source and the first output target"; // Add SRT medium to output targets, and keep input medium empty. - unique_ptr m { new TargetMedium }; - m->Setup(m_srt_relay.get()); - m_output_media.push_back(move(m)); + unique_ptr tm { new TargetMedium }; + tm->Setup(m_srt_relay.get()); + m_output_media.push_back(move(tm)); } else { diff --git a/testing/testactivemedia.cpp b/testing/testactivemedia.cpp index 9f2f03c98..44c96ee65 100644 --- a/testing/testactivemedia.cpp +++ b/testing/testactivemedia.cpp @@ -125,4 +125,20 @@ void TargetMedium::Runner() } } +bool TargetMedium::Schedule(const MediaPacket& data) +{ + LOGP(applog.Debug, "TargetMedium::Schedule LOCK ... "); + std::lock_guard lg(buffer_lock); + LOGP(applog.Debug, "TargetMedium::Schedule LOCKED - checking: running=", running, " interrupt=", ::transmit_int_state); + if (!running || ::transmit_int_state) + { + LOGP(applog.Debug, "TargetMedium::Schedule: not running, discarding packet"); + return false; + } + + LOGP(applog.Debug, "TargetMedium(", typeid(*med).name(), "): Schedule: [", data.payload.size(), "] CLIENT -> BUFFER"); + buffer.push_back(data); + ready.notify_one(); + return true; +} diff --git a/testing/testactivemedia.hpp b/testing/testactivemedia.hpp index 011dcbfe7..e92abbe0c 100644 --- a/testing/testactivemedia.hpp +++ b/testing/testactivemedia.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include "testmedia.hpp" @@ -29,7 +28,7 @@ struct Medium std::mutex buffer_lock; std::thread thr; std::condition_variable ready; - std::atomic running = {false}; + srt::sync::atomic running {false}; std::exception_ptr xp; // To catch exception thrown by a thread virtual void Runner() = 0; @@ -147,22 +146,7 @@ struct TargetMedium: Medium { void Runner() override; - bool Schedule(const MediaPacket& data) - { - LOGP(applog.Debug, "TargetMedium::Schedule LOCK ... "); - std::lock_guard lg(buffer_lock); - LOGP(applog.Debug, "TargetMedium::Schedule LOCKED - checking: running=", running, " interrupt=", ::transmit_int_state); - if (!running || ::transmit_int_state) - { - LOGP(applog.Debug, "TargetMedium::Schedule: not running, discarding packet"); - return false; - } - - LOGP(applog.Debug, "TargetMedium(", typeid(*med).name(), "): Schedule: [", data.payload.size(), "] CLIENT -> BUFFER"); - buffer.push_back(data); - ready.notify_one(); - return true; - } + bool Schedule(const MediaPacket& data); void Clear() { diff --git a/testing/testmedia.cpp b/testing/testmedia.cpp index 2d6635288..197ee2231 100755 --- a/testing/testmedia.cpp +++ b/testing/testmedia.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #if !defined(_WIN32) #include @@ -50,8 +49,8 @@ using srt_logging::SockStatusStr; using srt_logging::MemberStatusStr; #endif -std::atomic transmit_throw_on_interrupt {false}; -std::atomic transmit_int_state {false}; +srt::sync::atomic transmit_throw_on_interrupt {false}; +srt::sync::atomic transmit_int_state {false}; int transmit_bw_report = 0; unsigned transmit_stats_report = 0; size_t transmit_chunk_size = SRT_LIVE_DEF_PLSIZE; @@ -1059,8 +1058,8 @@ void SrtCommon::OpenGroupClient() if (!extras.empty()) { Verb() << "?" << extras[0] << VerbNoEOL; - for (size_t i = 1; i < extras.size(); ++i) - Verb() << "&" << extras[i] << VerbNoEOL; + for (size_t ei = 1; ei < extras.size(); ++ei) + Verb() << "&" << extras[ei] << VerbNoEOL; } Verb(); @@ -1130,15 +1129,15 @@ void SrtCommon::OpenGroupClient() // spread the setting on all sockets. ConfigurePost(m_sock); - for (size_t i = 0; i < targets.size(); ++i) + for (size_t ti = 0; ti < targets.size(); ++ti) { // As m_group_nodes is simply transformed into 'targets', // one index can be used to index them all. You don't // have to check if they have equal addresses because they // are equal by definition. - if (targets[i].id != -1 && targets[i].errorcode == SRT_SUCCESS) + if (targets[ti].id != -1 && targets[ti].errorcode == SRT_SUCCESS) { - m_group_nodes[i].socket = targets[i].id; + m_group_nodes[ti].socket = targets[ti].id; } } @@ -1159,12 +1158,12 @@ void SrtCommon::OpenGroupClient() } m_group_data.resize(size); - for (size_t i = 0; i < m_group_nodes.size(); ++i) + for (size_t ni = 0; ni < m_group_nodes.size(); ++ni) { - SRTSOCKET insock = m_group_nodes[i].socket; + SRTSOCKET insock = m_group_nodes[ni].socket; if (insock == -1) { - Verb() << "TARGET '" << sockaddr_any(targets[i].peeraddr).str() << "' connection failed."; + Verb() << "TARGET '" << sockaddr_any(targets[ni].peeraddr).str() << "' connection failed."; continue; } @@ -1194,11 +1193,11 @@ void SrtCommon::OpenGroupClient() NULL, NULL) != -1) { Verb() << "[C]" << VerbNoEOL; - for (int i = 0; i < len1; ++i) - Verb() << " " << ready_conn[i] << VerbNoEOL; + for (int ri = 0; ri < len1; ++ri) + Verb() << " " << ready_conn[ri] << VerbNoEOL; Verb() << "[E]" << VerbNoEOL; - for (int i = 0; i < len2; ++i) - Verb() << " " << ready_err[i] << VerbNoEOL; + for (int ri = 0; ri < len2; ++ri) + Verb() << " " << ready_err[ri] << VerbNoEOL; Verb() << ""; diff --git a/testing/testmedia.hpp b/testing/testmedia.hpp index be72471d1..470e825ef 100644 --- a/testing/testmedia.hpp +++ b/testing/testmedia.hpp @@ -15,7 +15,8 @@ #include #include #include -#include + +#include // use srt::sync::atomic instead of std::atomic for the sake of logging #include "apputil.hpp" #include "statswriter.hpp" @@ -25,7 +26,7 @@ extern srt_listen_callback_fn* transmit_accept_hook_fn; extern void* transmit_accept_hook_op; -extern std::atomic transmit_int_state; +extern srt::sync::atomic transmit_int_state; extern std::shared_ptr transmit_stats_writer; diff --git a/testing/testmediabase.hpp b/testing/testmediabase.hpp index 04a85d435..686198787 100644 --- a/testing/testmediabase.hpp +++ b/testing/testmediabase.hpp @@ -11,17 +11,17 @@ #ifndef INC_SRT_COMMON_TRANMITBASE_HPP #define INC_SRT_COMMON_TRANMITBASE_HPP -#include #include #include #include #include #include +#include "sync.h" #include "uriparser.hpp" typedef std::vector bytevector; -extern std::atomic transmit_throw_on_interrupt; +extern srt::sync::atomic transmit_throw_on_interrupt; extern int transmit_bw_report; extern unsigned transmit_stats_report; extern size_t transmit_chunk_size; From 96437026900b32f06aab567cc6bb824938366885 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Tue, 28 May 2024 21:21:06 +0200 Subject: [PATCH 14/41] Fixed a clang-reported warning (to trigger rebuilding) --- testing/srt-test-live.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/srt-test-live.cpp b/testing/srt-test-live.cpp index 17f4020dc..853ef87ad 100644 --- a/testing/srt-test-live.cpp +++ b/testing/srt-test-live.cpp @@ -301,7 +301,7 @@ extern "C" int SrtCheckGroupHook(void* , SRTSOCKET acpsock, int , const sockaddr size = sizeof gt; if (-1 != srt_getsockflag(acpsock, SRTO_GROUPTYPE, >, &size)) { - if (gt < Size(gtypes)) + if (size_t(gt) < Size(gtypes)) Verb() << " type=" << gtypes[gt] << VerbNoEOL; else Verb() << " type=" << int(gt) << VerbNoEOL; From f4ecbc19349f9a7e3580f164019d41345ed19212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Mon, 17 Jun 2024 11:39:11 +0200 Subject: [PATCH 15/41] Updated sfmt.h, fixed sync formatting --- srtcore/sfmt.h | 383 +++++++++++++++++++++++++++++++++++++++++++---- srtcore/sync.cpp | 14 +- 2 files changed, 356 insertions(+), 41 deletions(-) diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index 61bbd8914..7b10e03e9 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -331,36 +332,325 @@ inline form_memory_buffer<> apply_format_fix(TYPE, const char* fmt)\ // be used. They will be inserted if needed. SFMT_FORMAT_FIXER(int, "+- '#", "dioxX", "i", ""); -// Short is simple because it's aligned to int anyway SFMT_FORMAT_FIXER(short int, "+- '#", "dioxX", "hi", ""); - SFMT_FORMAT_FIXER(long int, "+- '#", "dioxX", "li", ""); - SFMT_FORMAT_FIXER(long long int, "+- '#", "dioxX", "lli", ""); SFMT_FORMAT_FIXER(unsigned int, "+- '#", "uoxX", "u", ""); - SFMT_FORMAT_FIXER(unsigned short int, "+- '#", "uoxX", "hu", ""); - SFMT_FORMAT_FIXER(unsigned long int, "+- '#", "uoxX", "lu", ""); - SFMT_FORMAT_FIXER(unsigned long long int, "+- '#", "uoxX", "llu", ""); SFMT_FORMAT_FIXER(double, "+- '#.", "EeFfgGaA", "g", ""); SFMT_FORMAT_FIXER(float, "+- '#.", "EeFfgGaA", "g", ""); SFMT_FORMAT_FIXER(long double, "+- '#.", "EeFfgGaA", "Lg", ""); -SFMT_FORMAT_FIXER(char, "", "c", "c", ""); -SFMT_FORMAT_FIXER(std::string, "", "s", "s", ""); -SFMT_FORMAT_FIXER(const char*, "", "s", "s", ""); -SFMT_FORMAT_FIXER(char*, "", "s", "s", ""); -SFMT_FORMAT_FIXER_TPL(size_t N, const char (&)[N], "", "s", "s", ""); -SFMT_FORMAT_FIXER_TPL(size_t N, char (&)[N], "", "s", "s", ""); -SFMT_FORMAT_FIXER_TPL(class Type, Type*, "", "p", "p", ""); +SFMT_FORMAT_FIXER(char, "-", "c", "c", ""); + +SFMT_FORMAT_FIXER(std::string, "-.", "s", "s", ""); +SFMT_FORMAT_FIXER(const char*, "-.", "s", "s", ""); +SFMT_FORMAT_FIXER(char*, "-.", "s", "s", ""); +SFMT_FORMAT_FIXER_TPL(size_t N, const char (&)[N], "-.", "s", "s", ""); +SFMT_FORMAT_FIXER_TPL(size_t N, char (&)[N], "-.", "s", "s", ""); +SFMT_FORMAT_FIXER_TPL(class Type, Type*, "-", "p", "p", ""); #undef SFMT_FORMAT_FIXER_TPL #undef SFMT_FORMAT_FIXER +template +struct const_copy +{ + static void copy(char* target, const char *source) + { + *target = *source; + return const_copy::copy(target + 1, source + 1); + } +}; + +template<> +struct const_copy<1> // 1 because the last item is the terminal '\0'. +{ + static void copy(char*, const char *) { } // do nothing, terminal value +}; + +// These maps must cover all allowed values, for safety. +static const char present_int_map[8] = { 'i', 'o', 'x', 'X', 'd', 'd', 'd', 'd'}; +static const char present_float_map[8] = { 'g', 'G', 'a', 'A', 'e', 'E', 'f', 'g' }; + +} + +struct sfmc +{ + enum postype { pos_no, pos_plus, pos_space, pos_invalid }; + enum flavor { + flavor_dec = 0, + flavor_oct = 1, + flavor_hex = 2, + flavor_uhex = 3, + + flavor_general = 0, + flavor_ugeneral = 1, + flavor_fhex = 2, + flavor_ufhex = 3, + flavor_scientific = 4, + flavor_uscientific = 5, + flavor_fixed = 6 + }; + +protected: + short widthval; + short precisionval; + bool widthbit:1; + bool precisionbit:1; + bool altbit:1; + bool leftbit:1; + bool leadzerobit:1; + postype postype:2; + flavor presentation:3; + bool localized:1; + +public: + sfmc(): + widthval(0), + precisionval(6), + widthbit(false), + precisionbit(false), + altbit(false), + leftbit(false), + leadzerobit(false), + postype(pos_no), + presentation(flavor_dec), + localized(false) + { + } + +#define SFMTC_TAG(name, body) sfmc& name () { body; return *this; } +#define SFMTC_TAG_VAL(name, body) sfmc& name (int val) { body; return *this; } + + SFMTC_TAG(alt, altbit = true); + SFMTC_TAG(left, leftbit = true); + SFMTC_TAG(right, (void)0); + SFMTC_TAG_VAL(width, widthbit = true; widthval = abs(val)); + SFMTC_TAG_VAL(precision, precisionbit = true; precisionval = abs(val)); + SFMTC_TAG(dec, (void)0); + SFMTC_TAG(hex, presentation = flavor_hex); + SFMTC_TAG(oct, presentation = flavor_oct); + SFMTC_TAG(uhex, presentation = flavor_uhex); + SFMTC_TAG(general, (void)0); + SFMTC_TAG(ugeneral, presentation = flavor_ugeneral); + SFMTC_TAG(fhex, presentation = flavor_fhex); + SFMTC_TAG(ufhex, presentation = flavor_ufhex); + SFMTC_TAG(exp, presentation = flavor_scientific); + SFMTC_TAG(uexp, presentation = flavor_uscientific); + SFMTC_TAG(scientific, presentation = flavor_scientific); + SFMTC_TAG(uscientific, presentation = flavor_uscientific); + SFMTC_TAG(fixed, presentation = flavor_fixed); + SFMTC_TAG(nopos, (void)0); + SFMTC_TAG(posspace, postype = pos_space); + SFMTC_TAG(posplus, postype = pos_plus); + SFMTC_TAG(fillzero, leadzerobit = true); + +#undef SFMTC_TAG +#undef SFMTC_TAG_VAL + + // Utility function to store the number for width/precision + // For C++11 it could be constexpr, but this is C++03-compat code. + // It's bound to this structure because it's unsafe. + static size_t store_number(char* position, int number) + { + size_t shiftpos = 0; + div_t dm = div(number, 10); + if (dm.quot) + shiftpos = store_number(position, dm.quot); + position[shiftpos] = '0' + dm.rem; + return shiftpos + 1; + } + + template + internal::form_memory_buffer<> create_format_int(const char (&lnspec)[N]) const + { + using namespace internal; + + Ensure= 2> c3; (void)c3; + + form_memory_buffer<> form; + + // Use reservation as this will be faster and also + // we don't know how many ciphers will be taken by width/precision + // We need to reserve 12 + 12 + 4 + 4 = 32. + char* buf = form.expose(32); + size_t used = 0; + buf[used++] = '%'; + + if (altbit) + buf[used++] = '#'; + + if (leftbit) + buf[used++] = '-'; + + if (localized) + buf[used++] = '\''; + + if (leadzerobit) + buf[used++] = '0'; + + if (widthbit) + { + size_t w = store_number(buf + used, widthval); + used += w; + } + + // That's it, now we copy the type length modifier + const_copy::copy(buf + used, lnspec); + used += (N - 2); + + // And finally the flavor modifier + if (int(presentation) == 0) + buf[used++] = lnspec[N-2]; + else + buf[used++] = present_int_map[presentation]; + buf[used] = '\0'; + + size_t unused = 32 - used; + if (unused > 0) + form.unreserve(unused); + form.commit(); + + return form; + } + + template + internal::form_memory_buffer<> create_format_float(const char (&lnspec)[N]) const + { + using namespace internal; + Ensure= 2> c3; (void)c3; + + form_memory_buffer<> form; + + // Use reservation as this will be faster and also + // we don't know how many ciphers will be taken by width/precision + // We need to reserve 12 + 12 + 4 + 4 = 32. + char* buf = form.expose(32); + size_t used = 0; + buf[used++] = '%'; + + if (altbit) + buf[used++] = '#'; + + if (leftbit) + buf[used++] = '-'; + + if (localized) + buf[used++] = '\''; + + if (leadzerobit) + buf[used++] = '0'; + + if (widthbit) + { + size_t w = store_number(buf + used, widthval); + used += w; + } + + if (precisionbit) + { + buf[used++] = '.'; + size_t w = store_number(buf + used, precisionval); + used += w; + } + + // That's it, now we copy the type length modifier + const_copy::copy(buf + used, lnspec); + used += (N - 2); + + // And finally the flavor modifier + if (int(presentation) == 0) + buf[used++] = lnspec[N-2]; + else + buf[used++] = present_float_map[presentation]; + buf[used] = '\0'; + + size_t unused = 32 - used; + if (unused > 0) + form.unreserve(unused); + form.commit(); + + return form; + } + + internal::form_memory_buffer<> create_format(int) const { return create_format_int("i"); } + internal::form_memory_buffer<> create_format(short int) const { return create_format_int("hi"); }; + internal::form_memory_buffer<> create_format(long int) const { return create_format_int("li"); }; + internal::form_memory_buffer<> create_format(long long int) const { return create_format_int("lli"); }; + + internal::form_memory_buffer<> create_format(unsigned int) const { return create_format_int("u"); }; + internal::form_memory_buffer<> create_format(unsigned short int) const { return create_format_int("hu"); }; + internal::form_memory_buffer<> create_format(unsigned long int) const { return create_format_int("lu"); }; + internal::form_memory_buffer<> create_format(unsigned long long int) const { return create_format_int("llu"); }; + + internal::form_memory_buffer<> create_format(double) const { return create_format_float("g"); }; + internal::form_memory_buffer<> create_format(float) const { return create_format_float("g"); }; + internal::form_memory_buffer<> create_format(long double) const { return create_format_float("Lg"); }; + + internal::form_memory_buffer<> create_format(char) const + { + internal::form_memory_buffer<> form; + form.append("%c", 3); + return form; + } + + internal::form_memory_buffer<> create_format_string() const + { + using namespace internal; + + form_memory_buffer<> form; + + // Use reservation as this will be faster and also + // we don't know how many ciphers will be taken by width/precision + // We need to reserve 12 + 12 + 4 + 4 = 32. + char* buf = form.expose(32); + size_t used = 0; + buf[used++] = '%'; + + if (leftbit) + buf[used++] = '-'; + + if (widthbit) + { + size_t w = store_number(buf + used, widthval); + used += w; + } + + if (precisionbit) + { + buf[used++] = '.'; + size_t w = store_number(buf + used, precisionval); + used += w; + } + + // No modifier supported + // XXX NOTE: wchar_t therefore not supported! + buf[used++] = 's'; + buf[used] = '\0'; + + size_t unused = 32 - used; + if (unused > 0) + form.unreserve(unused); + form.commit(); + + return form; + } + + internal::form_memory_buffer<> create_format(char*) const { return create_format_string(); }; + internal::form_memory_buffer<> create_format(const char*) const { return create_format_string(); }; + internal::form_memory_buffer<> create_format(std::string) const { return create_format_string(); }; +}; + +// fmt(val, sfmc().alt().hex().width(10)) + +namespace internal +{ + template inline void write_default(Stream& str, const Value& val); @@ -628,25 +918,14 @@ static inline size_t SNPrintfOne(char* buf, size_t bufsize, const char* fmt, con { return std::snprintf(buf, bufsize, fmt, val.c_str()); } -} template inline -internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) +form_memory_buffer<> sfmt_imp(const Value& val, const form_memory_buffer<>& fstr, size_t bufsize) { - using namespace internal; - - form_memory_buffer<> fstr = apply_format_fix(val, fmtspec); form_memory_buffer<> out; - size_t bufsize = form_memory_buffer<>::INITIAL_SIZE; - // Reserve the maximum initial first, then shrink. char* buf = out.expose(bufsize); - // We want to use this buffer as a NUL-terminated string. - // So we need to add NUL character oursevles, form_memory_buffer<> - // doesn't do it an doesn't use the NUL-termination. - fstr.append('\0'); - size_t valsize = SNPrintfOne(buf, bufsize, fstr.get_first(), val); // Deemed impossible to happen, but still @@ -669,6 +948,35 @@ internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) out.commit(); return out; } +} + +template inline +internal::form_memory_buffer<> sfmt(const Value& val, const char* fmtspec = 0) +{ + using namespace internal; + + form_memory_buffer<> fstr = apply_format_fix(val, fmtspec); + size_t bufsize = form_memory_buffer<>::INITIAL_SIZE; + + // We want to use this buffer as a NUL-terminated string. + // So we need to add NUL character oursevles, form_memory_buffer<> + // doesn't do it an doesn't use the NUL-termination. + fstr.append('\0'); + + return sfmt_imp(val, fstr, bufsize); +} + +template inline +internal::form_memory_buffer<> sfmt(const Value& val, const sfmc& config) +{ + using namespace internal; + + form_memory_buffer<> fstr = config.create_format(val); + size_t bufsize = form_memory_buffer<>::INITIAL_SIZE; + return sfmt_imp(val, fstr, bufsize); +} + + namespace internal { @@ -677,21 +985,16 @@ void write_default(Stream& s, const Value& v) { s << sfmt(v, ""); } -} -template -std::string sfmts(const Value& val, const char* fmtspec = 0) +inline void sfmts_imp(const internal::form_memory_buffer<>& b, std::string& out) { using namespace internal; - std::string out; - form_memory_buffer<> b = sfmt(val, fmtspec); if (b.size() == 0) - return out; + return; out.reserve(b.size()); - out.append(b.get_first(), b.first_size()); for (form_memory_buffer<>::slices_t::const_iterator i = b.get_slices().begin(); i != b.get_slices().end(); ++i) @@ -699,10 +1002,26 @@ std::string sfmts(const Value& val, const char* fmtspec = 0) const char* data = &(*i)[0]; out.append(data, i->size()); } +} +} +template +inline std::string sfmts(const Value& val, const char* fmtspec = 0) +{ + std::string out; + internal::sfmts_imp(sfmt(val, fmtspec), (out)); return out; } +template +inline std::string sfmts(const Value& val, const sfmc& fmtspec) +{ + std::string out; + internal::sfmts_imp(sfmt(val, fmtspec), (out)); + return out; +} + + // Semi-manipulator to add the end-of-line. const internal::form_memory_buffer<2> seol ("\n"); diff --git a/srtcore/sync.cpp b/srtcore/sync.cpp index e4e511fb5..9dcaabb54 100644 --- a/srtcore/sync.cpp +++ b/srtcore/sync.cpp @@ -50,21 +50,17 @@ std::string FormatTime(const steady_clock::time_point& timestamp) const uint64_t hours = total_sec / (60 * 60) - days * 24; const uint64_t minutes = total_sec / 60 - (days * 24 * 60) - hours * 60; const uint64_t seconds = total_sec - (days * 24 * 60 * 60) - hours * 60 * 60 - minutes * 60; - - // Temporary solution. Need to find some better handling - // of dynamic width and precision. - fmt::obufstream dfmts; - dfmts << "0" << decimals; - dfmts.append('\0'); // form_memory_buffer doesn't use NUL-termination. - const char* decimal_fmt = dfmts.bufptr(); - + steady_clock::time_point frac = timestamp - seconds_from(total_sec); fmt::obufstream out; if (days) out << days << "D "; + out << fmt::sfmt(hours, "02") << ":" << fmt::sfmt(minutes, "02") << ":" << fmt::sfmt(seconds, "02") << "." - << fmt::sfmt((timestamp - seconds_from(total_sec)).time_since_epoch().count(), decimal_fmt) << " [STDY]"; + << fmt::sfmt(frac.time_since_epoch().count(), + fmt::sfmc().fillzero().width(decimals)) + << " [STDY]"; return out.str(); } From 0a607c7c30da6aa35291a36b877c6445c711cdf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Tue, 18 Jun 2024 18:38:05 +0200 Subject: [PATCH 16/41] Some cosmetic fixes. Fixed the use of std::abs --- srtcore/core.cpp | 24 +++++++++++++----------- srtcore/logging.h | 6 +++--- srtcore/sfmt.h | 4 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/srtcore/core.cpp b/srtcore/core.cpp index f87692caa..456d17ab1 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -89,11 +89,12 @@ using namespace srt; using namespace srt::sync; using namespace srt_logging; using fmt::sfmt; +using fmt::sfmc; const SRTSOCKET UDT::INVALID_SOCK = srt::CUDT::INVALID_SOCK; const int UDT::ERROR = srt::CUDT::ERROR; -static const char onoff[2] = {'-', '+'}; +static inline char fmt_onoff(bool val) { return val ? '+' : '-'; } //#define SRT_CMD_HSREQ 1 /* SRT Handshake Request (sender) */ #define SRT_CMD_HSREQ_MINSZ 8 /* Minumum Compatible (1.x.x) packet size (bytes) */ @@ -1777,10 +1778,10 @@ bool srt::CUDT::createSrtHandshake( LOGC(cnlog.Error, log << CONID() << "createSrtHandshake: IPE: need to send KM, but CryptoControl does not exist." << " Socket state: " - << onoff[m_bConnected] << "connected, " - << onoff[m_bConnecting] << "connecting, " - << onoff[m_bBroken] << "broken, " - << onoff[m_bClosing] << "closing."); + << fmt_onoff(m_bConnected) << "connected, " + << fmt_onoff(m_bConnecting) << "connecting, " + << fmt_onoff(m_bBroken) << "broken, " + << fmt_onoff(m_bClosing) << "closing."); return false; } @@ -4109,11 +4110,11 @@ EConnectStatus srt::CUDT::craftKmResponse(uint32_t* aw_kmdata, size_t& w_kmdatas LOGC(cnlog.Error, log << CONID() << "IPE: craftKmResponse needs to send KM, but CryptoControl does not exist." << " Socket state: " - << onoff[m_bConnected] << "connected, " - << onoff[m_bConnecting] << "connecting, " - << onoff[m_bBroken] << "broken, " - << onoff[m_bOpened] << "opened, " - << onoff[m_bClosing] << "closing."); + << fmt_onoff(m_bConnected) << "connected, " + << fmt_onoff(m_bConnecting) << "connecting, " + << fmt_onoff(m_bBroken) << "broken, " + << fmt_onoff(m_bOpened) << "opened, " + << fmt_onoff(m_bClosing) << "closing."); return CONN_REJECT; } // This is a periodic handshake update, so you need to extract the KM data from the @@ -7777,7 +7778,8 @@ bool srt::CUDT::updateCC(ETransmissionEvent evt, const EventVariant arg) #if ENABLE_HEAVY_LOGGING HLOGC(rslog.Debug, log << CONID() << "updateCC: updated values from congctl: interval=" << FormatDuration(m_tdSendInterval) - << " (cfg:" << m_CongCtl->pktSndPeriod_us() << "us) cgwindow=" << sfmt(cgwindow, ".3")); + << " (cfg:" << m_CongCtl->pktSndPeriod_us() << "us) cgwindow=" + << sfmt(cgwindow, sfmc().precision(3))); #endif } diff --git a/srtcore/logging.h b/srtcore/logging.h index 94cda07be..c7ff11704 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -342,7 +342,7 @@ struct LogDispatcher::Proxy template Proxy& operator<<(const srt::sync::atomic& arg) { - if ( that_enabled ) + if (that_enabled) { os << arg.load(); } @@ -376,9 +376,9 @@ struct LogDispatcher::Proxy ~Proxy() { - if ( that_enabled ) + if (that_enabled) { - if ( (flags & SRT_LOGF_DISABLE_EOL) == 0 ) + if ((flags & SRT_LOGF_DISABLE_EOL) == 0) os << fmt::seol; that.SendLogLine(i_file, i_line, area, os.str()); } diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index 1db88bba7..b6eecf451 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -430,8 +430,8 @@ struct sfmc SFMTC_TAG(alt, altbit = true); SFMTC_TAG(left, leftbit = true); SFMTC_TAG(right, (void)0); - SFMTC_TAG_VAL(width, widthbit = true; widthval = abs(val)); - SFMTC_TAG_VAL(precision, precisionbit = true; precisionval = abs(val)); + SFMTC_TAG_VAL(width, widthbit = true; widthval = std::abs(val)); + SFMTC_TAG_VAL(precision, precisionbit = true; precisionval = std::abs(val)); SFMTC_TAG(dec, (void)0); SFMTC_TAG(hex, presentation = flavor_hex); SFMTC_TAG(oct, presentation = flavor_oct); From d2ec1cf653a0800decc167c538c7f2d40c2caf97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Wed, 19 Jun 2024 09:12:30 +0200 Subject: [PATCH 17/41] Fixed usage of with std --- srtcore/sfmt.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index b6eecf451..715e7aa96 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -260,8 +260,8 @@ form_memory_buffer<> fix_format(const char* fmt, // All these arrays must contain at least 2 elements, // that is one character and terminating zero. //Ensure= 2> c1; - Ensure= 2> c2; (void)c2; - Ensure= 2> c3; (void)c3; + Ensure= 2)> c2; (void)c2; + Ensure= 2)> c3; (void)c3; form_memory_buffer<> buf; buf.append('%'); @@ -311,7 +311,7 @@ form_memory_buffer<> fix_format(const char* fmt, inline form_memory_buffer<> apply_format_fix(TYPE, const char* fmt) \ { \ return fix_format(fmt, ALLOWED, TYPED, DEFTYPE, WARN); \ -} +} #define SFMT_FORMAT_FIXER_TPL(TPAR, TYPE, ALLOWED, TYPED, DEFTYPE, WARN) \ template\ @@ -456,10 +456,10 @@ struct sfmc // Utility function to store the number for width/precision // For C++11 it could be constexpr, but this is C++03-compat code. // It's bound to this structure because it's unsafe. - static size_t store_number(char* position, int number) + static std::size_t store_number(char* position, int number) { - size_t shiftpos = 0; - div_t dm = div(number, 10); + std::size_t shiftpos = 0; + std::div_t dm = std::div(number, 10); if (dm.quot) shiftpos = store_number(position, dm.quot); position[shiftpos] = '0' + dm.rem; @@ -471,7 +471,7 @@ struct sfmc { using namespace internal; - Ensure= 2> c3; (void)c3; + Ensure= 2)> c3; (void)c3; form_memory_buffer<> form; From 193fe39d3010ecf8eb2b3209eee5f8129220eaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Wed, 19 Jun 2024 09:52:06 +0200 Subject: [PATCH 18/41] Fixed correct includes for std::div --- srtcore/sfmt.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srtcore/sfmt.h b/srtcore/sfmt.h index 715e7aa96..fc653d757 100644 --- a/srtcore/sfmt.h +++ b/srtcore/sfmt.h @@ -15,7 +15,8 @@ #include #include -#include +#include // std::abs +#include // std::div #include #include #include From c81d4d609757fc3bce37d7b751f8de4a21441cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Thu, 20 Jun 2024 15:05:25 +0200 Subject: [PATCH 19/41] Renamed sfmt.h and moved to srt namespace --- apps/logsupport.cpp | 2 +- apps/uriparser.cpp | 2 +- srtcore/api.cpp | 4 +-- srtcore/common.cpp | 6 ++-- srtcore/congctl.cpp | 2 +- srtcore/core.cpp | 6 ++-- srtcore/logging.cpp | 4 +-- srtcore/logging.h | 14 ++++---- srtcore/queue.cpp | 2 +- srtcore/socketconfig.cpp | 2 -- srtcore/{sfmt.h => srt_sfmt.h} | 11 +++++- srtcore/sync.cpp | 16 ++++----- srtcore/sync.h | 6 ++-- srtcore/utilities.h | 62 ++++++++-------------------------- 14 files changed, 55 insertions(+), 84 deletions(-) rename srtcore/{sfmt.h => srt_sfmt.h} (95%) diff --git a/apps/logsupport.cpp b/apps/logsupport.cpp index 7192f4596..86deb1690 100644 --- a/apps/logsupport.cpp +++ b/apps/logsupport.cpp @@ -173,7 +173,7 @@ set SrtParseLogFA(string fa, set* punknown) void ParseLogFASpec(const vector& speclist, string& w_on, string& w_off) { - fmt::obufstream son, soff; + srt::obufstream son, soff; for (auto& s: speclist) { diff --git a/apps/uriparser.cpp b/apps/uriparser.cpp index 47e8f6a7f..7425bca03 100644 --- a/apps/uriparser.cpp +++ b/apps/uriparser.cpp @@ -64,7 +64,7 @@ string UriParser::makeUri() prefix = m_proto + "://"; } - fmt::obufstream out; + srt::obufstream out; out << prefix << m_host; if ((m_port == "" || m_port == "0") && m_expect == EXPECT_FILE) diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 93ad23725..b436bda1b 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -231,7 +231,7 @@ string srt::CUDTUnited::CONID(SRTSOCKET sock) if (sock == 0) return ""; - fmt::obufstream os; + srt::obufstream os; os << "@" << sock << ":"; return os.str(); } @@ -3249,7 +3249,7 @@ bool srt::CUDTUnited::updateListenerMux(CUDTSocket* s, const CUDTSocket* ls) CMultiplexer& m = i->second; #if ENABLE_HEAVY_LOGGING - fmt::obufstream that_muxer; + srt::obufstream that_muxer; that_muxer << "id=" << m.m_iID << " port=" << m.m_iPort << " ip=" << (m.m_iIPversion == AF_INET ? "v4" : "v6"); #endif diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 843420354..5bc849248 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -277,10 +277,10 @@ void srt::CIPAddress::pton(sockaddr_any& w_addr, const uint32_t ip[4], const soc } else { - fmt::obufstream peeraddr_form; - peeraddr_form << fmt::sfmt(peeraddr16[0], "04x"); + obufstream peeraddr_form; + peeraddr_form << sfmt(peeraddr16[0], "04x"); for (int i = 1; i < 8; ++i) - peeraddr_form << ":" << fmt::sfmt(peeraddr16[i], "04x"); + peeraddr_form << ":" << sfmt(peeraddr16[i], "04x"); LOGC(inlog.Error, log << "pton: IPE or net error: can't determine IPv4 carryover format: " << peeraddr_form); *target_ipv4_addr = 0; diff --git a/srtcore/congctl.cpp b/srtcore/congctl.cpp index 0f6edb15b..cd7d126f6 100644 --- a/srtcore/congctl.cpp +++ b/srtcore/congctl.cpp @@ -595,7 +595,7 @@ class FileCC : public SrtCongestionControlBase { m_dPktSndPeriod = m_dCWndSize / (m_parent->SRTT() + m_iRCInterval); HLOGC(cclog.Debug, log << "FileCC: CHKTIMER, SLOWSTART:OFF, sndperiod=" << m_dPktSndPeriod << "us AS wndsize/(RTT+RCIV) (wndsize=" - << fmt::sfmt(m_dCWndSize, ".6") << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); + << sfmt(m_dCWndSize, ".6") << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); } } else diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 456d17ab1..701f0b0a6 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -88,8 +88,6 @@ using namespace std; using namespace srt; using namespace srt::sync; using namespace srt_logging; -using fmt::sfmt; -using fmt::sfmc; const SRTSOCKET UDT::INVALID_SOCK = srt::CUDT::INVALID_SOCK; const int UDT::ERROR = srt::CUDT::ERROR; @@ -10014,9 +10012,9 @@ int srt::CUDT::checkLazySpawnTsbPdThread() HLOGP(qrlog.Debug, "Spawning Socket TSBPD thread"); #if ENABLE_HEAVY_LOGGING - fmt::obufstream buf; + obufstream buf; // Take the last 2 ciphers from the socket ID. - string s = fmt::sfmts(m_SocketID, "02"); + string s = sfmts(m_SocketID, "02"); buf << "SRT:TsbPd:@" << s.substr(s.size()-2, 2); const string thname = buf.str(); #else diff --git a/srtcore/logging.cpp b/srtcore/logging.cpp index 8ccfa30f1..e76e6db9a 100644 --- a/srtcore/logging.cpp +++ b/srtcore/logging.cpp @@ -43,7 +43,7 @@ LogDispatcher::Proxy LogDispatcher::operator()() return Proxy(*this); } -void LogDispatcher::CreateLogLinePrefix(fmt::obufstream& serr) +void LogDispatcher::CreateLogLinePrefix(srt::obufstream& serr) { using namespace std; using namespace srt; @@ -60,7 +60,7 @@ void LogDispatcher::CreateLogLinePrefix(fmt::obufstream& serr) if (strftime(tmp_buf, sizeof(tmp_buf), "%X.", &tm)) { - serr << tmp_buf << fmt::sfmt(tv.tv_usec, "06"); + serr << tmp_buf << srt::sfmt(tv.tv_usec, "06"); } } diff --git a/srtcore/logging.h b/srtcore/logging.h index c7ff11704..cefa5b7ce 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -28,7 +28,7 @@ written by #include #endif -#include "sfmt.h" +#include "srt_sfmt.h" #include "srt.h" #include "utilities.h" @@ -193,7 +193,7 @@ struct SRT_API LogDispatcher bool CheckEnabled(); - void CreateLogLinePrefix(fmt::obufstream&); + void CreateLogLinePrefix(srt::obufstream&); void SendLogLine(const char* file, int line, const std::string& area, const std::string& sl); // log.Debug("This is the ", nth, " time"); <--- C++11 only. @@ -286,7 +286,7 @@ struct LogDispatcher::Proxy { LogDispatcher& that; - fmt::obufstream os; + srt::obufstream os; // Cache the 'enabled' state in the beginning. If the logging // becomes enabled or disabled in the middle of the log, we don't @@ -379,7 +379,7 @@ struct LogDispatcher::Proxy if (that_enabled) { if ((flags & SRT_LOGF_DISABLE_EOL) == 0) - os << fmt::seol; + os << srt::seol; that.SendLogLine(i_file, i_line, area, os.str()); } // Needed in destructor? @@ -473,10 +473,10 @@ inline bool LogDispatcher::CheckEnabled() //extern std::mutex Debug_mutex; -inline void PrintArgs(fmt::obufstream&) {} +inline void PrintArgs(srt::obufstream&) {} template -inline void PrintArgs(fmt::obufstream& serr, Arg1&& arg1, Args&&... args) +inline void PrintArgs(srt::obufstream& serr, Arg1&& arg1, Args&&... args) { serr << std::forward(arg1); PrintArgs(serr, args...); @@ -484,7 +484,7 @@ inline void PrintArgs(fmt::obufstream& serr, Arg1&& arg1, Args&&... args) // Add exceptional handling for sync::atomic template -inline void PrintArgs(fmt::obufstream& serr, const srt::sync::atomic& arg1, Args&&... args) +inline void PrintArgs(srt::obufstream& serr, const srt::sync::atomic& arg1, Args&&... args) { serr << arg1.load(); PrintArgs(serr, args...); diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp index 78de6a6b9..43f7349fc 100644 --- a/srtcore/queue.cpp +++ b/srtcore/queue.cpp @@ -1079,7 +1079,7 @@ bool srt::CRendezvousQueue::qualifyToHandle(EReadStatus rst, { HLOGC(cnlog.Debug, log << "RID: socket @" << i->m_iID << " still active (remaining " - << fmt::sfmt(count_microseconds(i->m_tsTTL - tsNow) / 1000000.0, "f") << "s of TTL)..."); + << sfmt(count_microseconds(i->m_tsTTL - tsNow) / 1000000.0, "f") << "s of TTL)..."); } const steady_clock::time_point tsLastReq = i->m_pUDT->m_tsLastReqTime; diff --git a/srtcore/socketconfig.cpp b/srtcore/socketconfig.cpp index cec4845b4..6d1acf754 100644 --- a/srtcore/socketconfig.cpp +++ b/srtcore/socketconfig.cpp @@ -52,8 +52,6 @@ written by #include "srt.h" #include "socketconfig.h" -using fmt::sfmt; - namespace srt { int RcvBufferSizeOptionToValue(int val, int flightflag, int mss) diff --git a/srtcore/sfmt.h b/srtcore/srt_sfmt.h similarity index 95% rename from srtcore/sfmt.h rename to srtcore/srt_sfmt.h index fc653d757..e11b0b730 100644 --- a/srtcore/sfmt.h +++ b/srtcore/srt_sfmt.h @@ -1,3 +1,12 @@ +// SOURCE NOTE: +// +// This is copied directly from a public-domain library: +// +// URI: https://github.com/ethouris/fmt +// PATH: include/fmt/sfmt.h +// +// with slight modifications. +// // Formatting library for C++ - C++03 compat version of on-demand tagged format API. // // Copyright (c) 2024 - present, Mikołaj Małecki @@ -21,7 +30,7 @@ #include #include -namespace fmt +namespace srt { namespace internal diff --git a/srtcore/sync.cpp b/srtcore/sync.cpp index 9dcaabb54..ff7473ca3 100644 --- a/srtcore/sync.cpp +++ b/srtcore/sync.cpp @@ -51,15 +51,15 @@ std::string FormatTime(const steady_clock::time_point& timestamp) const uint64_t minutes = total_sec / 60 - (days * 24 * 60) - hours * 60; const uint64_t seconds = total_sec - (days * 24 * 60 * 60) - hours * 60 * 60 - minutes * 60; steady_clock::time_point frac = timestamp - seconds_from(total_sec); - fmt::obufstream out; + srt::obufstream out; if (days) out << days << "D "; - out << fmt::sfmt(hours, "02") << ":" - << fmt::sfmt(minutes, "02") << ":" - << fmt::sfmt(seconds, "02") << "." - << fmt::sfmt(frac.time_since_epoch().count(), - fmt::sfmc().fillzero().width(decimals)) + out << srt::sfmt(hours, "02") << ":" + << srt::sfmt(minutes, "02") << ":" + << srt::sfmt(seconds, "02") << "." + << srt::sfmt(frac.time_since_epoch().count(), + srt::sfmc().fillzero().width(decimals)) << " [STDY]"; return out.str(); } @@ -76,8 +76,8 @@ std::string FormatTimeSys(const steady_clock::time_point& timestamp) char tmp_buf[512]; strftime(tmp_buf, 512, "%X.", &tm); - fmt::obufstream out; - out << tmp_buf << fmt::sfmt(count_microseconds(timestamp.time_since_epoch()) % 1000000, "06") << " [SYST]"; + srt::obufstream out; + out << tmp_buf << srt::sfmt(count_microseconds(timestamp.time_since_epoch()) % 1000000, "06") << " [SYST]"; return out.str(); } diff --git a/srtcore/sync.h b/srtcore/sync.h index 627f7eac5..40584a838 100644 --- a/srtcore/sync.h +++ b/srtcore/sync.h @@ -55,7 +55,7 @@ #include "srt.h" #include "utilities.h" #include "srt_attr_defs.h" -#include "sfmt.h" +#include "srt_sfmt.h" namespace srt { @@ -775,8 +775,8 @@ struct DurationUnitName template inline std::string FormatDuration(const steady_clock::duration& dur) { - fmt::obufstream out; - out << fmt::sfmt(DurationUnitName::count(dur), "f") << DurationUnitName::name(); + obufstream out; + out << sfmt(DurationUnitName::count(dur), "f") << DurationUnitName::name(); return out.str(); } diff --git a/srtcore/utilities.h b/srtcore/utilities.h index 83405b44c..d7f353765 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -45,7 +45,7 @@ written by #include #include -#include "sfmt.h" +#include "srt_sfmt.h" // -------------- UTILITIES ------------------------ @@ -485,7 +485,7 @@ class FixedArray void throw_invalid_index(int i) const { - fmt::obufstream ss; + srt::obufstream ss; ss << "Index " << i << "out of range"; throw std::runtime_error(ss.str()); } @@ -587,7 +587,7 @@ inline Stream& Print(Stream& sout, Arg1&& arg1, Args&&... args) template inline std::string Sprint(Args&&... args) { - fmt::obufstream sout; + srt::obufstream sout; Print(sout, args...); return sout.str(); } @@ -673,14 +673,14 @@ class UniquePtr: public std::auto_ptr template inline std::string Sprint(const Arg1& arg) { - return fmt::sfmts(arg); + return srt::sfmts(arg); } // Ok, let it be 2-arg, in case when a manipulator is needed template inline std::string Sprint(const Arg1& arg1, const Arg2& arg2) { - fmt::obufstream sout; + srt::obufstream sout; sout << arg1 << arg2; return sout.str(); } @@ -718,11 +718,11 @@ typename Map::mapped_type const* map_getp(const Map& m, const Key& key) template inline std::string Printable(const Container& in, Value /*pseudoargument*/, const char* fmt = 0) { - fmt::obufstream os; + srt::obufstream os; os << "[ "; typedef typename Container::const_iterator it_t; for (it_t i = in.begin(); i != in.end(); ++i) - os << fmt::sfmt(*i, fmt) << " "; + os << srt::sfmt(*i, fmt) << " "; os << "]"; return os.str(); } @@ -732,11 +732,11 @@ template inline std::string Printable(const Container& in, std::pair/*pseudoargument*/, const char* fmtk = 0, const char* fmtv = 0) { using namespace srt_pair_op; - fmt::obufstream os; + srt::obufstream os; os << "[ "; typedef typename Container::const_iterator it_t; for (it_t i = in.begin(); i != in.end(); ++i) - os << fmt::sfmt(i->first, fmtk) << ":" << fmt::sfmt(i->second, fmtv) << " "; + os << srt::sfmt(i->first, fmtk) << ":" << srt::sfmt(i->second, fmtv) << " "; os << "]"; return os.str(); } @@ -757,7 +757,7 @@ std::string PrintableMod(const Container& in, const std::string& prefix) { using namespace srt_pair_op; typedef typename Container::value_type Value; - fmt::obufstream os; + srt::obufstream os; os << "[ "; for (typename Container::const_iterator y = in.begin(); y != in.end(); ++y) os << prefix << Value(*y) << " "; @@ -980,47 +980,13 @@ inline std::string FormatBinaryString(const uint8_t* bytes, size_t size) if ( size == 0 ) return ""; - using namespace fmt; + srt::obufstream os; - obufstream os; - - os << sfmt(bytes[0], "02X"); - for (size_t i = 1; i < size; ++i) - { - os << sfmt(bytes[i], "02X"); - } - return os.str(); - - /* OLD VERSION - - //char buf[256]; - using namespace std; - - ostringstream os; - - // I know, it's funny to use sprintf and ostringstream simultaneously, - // but " %02X" in iostream is: << " " << hex << uppercase << setw(2) << setfill('0') << VALUE << setw(1) - // Too noisy. OTOH ostringstream solves the problem of memory allocation - // for a string of unpredictable size. - //sprintf(buf, "%02X", int(bytes[0])); - - os.fill('0'); - os.width(2); - os.setf(ios::basefield, ios::hex); - os.setf(ios::uppercase); - - //os << buf; - os << int(bytes[0]); - - - for (size_t i = 1; i < size; ++i) + for (size_t i = 0; i < size; ++i) { - //sprintf(buf, " %02X", int(bytes[i])); - //os << buf; - os << int(bytes[i]); + os << srt::sfmt(bytes[i], "02X"); } return os.str(); - */ } @@ -1184,7 +1150,7 @@ inline std::string BufferStamp(const char* mem, size_t size) } // Convert to hex string - return fmt::sfmts(sum, "08X"); + return srt::sfmts(sum, "08X"); } template From 0920fbf7f3d2e2b380e0d5d90e7729354e586f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Tue, 25 Jun 2024 12:08:03 +0200 Subject: [PATCH 20/41] [core] Setting up fmt with iomanip for logging system --- srtcore/api.cpp | 2 +- srtcore/common.cpp | 4 +- srtcore/congctl.cpp | 2 +- srtcore/core.cpp | 14 +++---- srtcore/logging.cpp | 22 +++++------ srtcore/logging.h | 46 ++++++++++++----------- srtcore/queue.cpp | 2 +- srtcore/socketconfig.cpp | 8 ++-- srtcore/srt_sfmt.h | 6 +++ srtcore/sync.cpp | 14 ++++--- srtcore/utilities.h | 80 +++++++++++++++++++++++++++++++++------- 11 files changed, 131 insertions(+), 69 deletions(-) diff --git a/srtcore/api.cpp b/srtcore/api.cpp index b436bda1b..840ef3acd 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -1405,7 +1405,7 @@ int srt::CUDTUnited::groupConnect(CUDTGroup* pg, SRT_SOCKGROUPCONFIG* targets, i for (size_t i = 0; i < g.m_config.size(); ++i) { HLOGC(aclog.Debug, log << "groupConnect: OPTION @" << sid << " #" << g.m_config[i].so); - error_reason = "group-derived option: #" + Sprint(g.m_config[i].so); + error_reason = Sprint("group-derived option: #", g.m_config[i].so); ns->core().setOpt(g.m_config[i].so, &g.m_config[i].value[0], (int)g.m_config[i].value.size()); } diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 5bc849248..acef9ee77 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -278,9 +278,9 @@ void srt::CIPAddress::pton(sockaddr_any& w_addr, const uint32_t ip[4], const soc else { obufstream peeraddr_form; - peeraddr_form << sfmt(peeraddr16[0], "04x"); + peeraddr_form << fmt(peeraddr16[0], hex, setfill('0'), setw(4)); for (int i = 1; i < 8; ++i) - peeraddr_form << ":" << sfmt(peeraddr16[i], "04x"); + peeraddr_form << ":" << fmt(peeraddr16[i], hex, setfill('0'), setw(4)); LOGC(inlog.Error, log << "pton: IPE or net error: can't determine IPv4 carryover format: " << peeraddr_form); *target_ipv4_addr = 0; diff --git a/srtcore/congctl.cpp b/srtcore/congctl.cpp index cd7d126f6..012d766b5 100644 --- a/srtcore/congctl.cpp +++ b/srtcore/congctl.cpp @@ -595,7 +595,7 @@ class FileCC : public SrtCongestionControlBase { m_dPktSndPeriod = m_dCWndSize / (m_parent->SRTT() + m_iRCInterval); HLOGC(cclog.Debug, log << "FileCC: CHKTIMER, SLOWSTART:OFF, sndperiod=" << m_dPktSndPeriod << "us AS wndsize/(RTT+RCIV) (wndsize=" - << sfmt(m_dCWndSize, ".6") << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); + << fmt(m_dCWndSize, setprecision(6)) << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); } } else diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 701f0b0a6..9eec4a9ae 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -2107,8 +2107,8 @@ int srt::CUDT::processSrtMsg_HSREQ(const uint32_t *srtdata, size_t bytelen, uint } LOGC(cnlog.Debug, log << "HSREQ/rcv: cmd=" << SRT_CMD_HSREQ << "(HSREQ) len=" << bytelen - << " vers=0x" << sfmt(srtdata[SRT_HS_VERSION], "x") - << " opts=0x" << sfmt(srtdata[SRT_HS_FLAGS], "x") + << " vers=0x" << fmt(srtdata[SRT_HS_VERSION], hex) + << " opts=0x" << fmt(srtdata[SRT_HS_FLAGS], hex) << " delay=" << SRT_HS_LATENCY_RCV::unwrap(srtdata[SRT_HS_LATENCY])); m_uPeerSrtVersion = srtdata[SRT_HS_VERSION]; @@ -2343,7 +2343,7 @@ int srt::CUDT::processSrtMsg_HSRSP(const uint32_t *srtdata, size_t bytelen, uint m_uPeerSrtFlags = srtdata[SRT_HS_FLAGS]; HLOGC(cnlog.Debug, log << "HSRSP/rcv: Version: " << SrtVersionString(m_uPeerSrtVersion) - << " Flags: SND:" << sfmt(m_uPeerSrtFlags, "08x") + << " Flags: SND:" << fmt(m_uPeerSrtFlags, hex, setfill('0'), setw(8)) << " (" << SrtFlagString(m_uPeerSrtFlags) << ")"); // Basic version check if (m_uPeerSrtVersion < m_config.uMinimumPeerSrtVersion) @@ -5470,14 +5470,14 @@ void * srt::CUDT::tsbpd(void* param) HLOGC(tslog.Debug, log << self->CONID() << "tsbpd: DROPSEQ: up to seqno %" << CSeqNo::decseq(info.seqno) << " (" << iDropCnt << " packets) playable at " << FormatTime(info.tsbpd_time) << " delayed " - << (timediff_us / 1000) << "." << sfmt(timediff_us % 1000, "03") << " ms"); + << (timediff_us / 1000) << "." << fmt(timediff_us % 1000, fixed, setfill('0'), setw(3)) << " ms"); #endif string why; if (self->frequentLogAllowed(FREQLOGFA_RCV_DROPPED, tnow, (why))) { LOGC(brlog.Warn, log << self->CONID() << "RCV-DROPPED " << iDropCnt << " packet(s). Packet seqno %" << info.seqno << " delayed for " << (timediff_us / 1000) << "." - << sfmt(timediff_us % 1000, "03") << " ms " << why); + << fmt(timediff_us % 1000, fixed, setfill('0'), setw(3)) << " ms " << why); } #if SRT_ENABLE_FREQUENT_LOG_TRACE else @@ -7777,7 +7777,7 @@ bool srt::CUDT::updateCC(ETransmissionEvent evt, const EventVariant arg) HLOGC(rslog.Debug, log << CONID() << "updateCC: updated values from congctl: interval=" << FormatDuration(m_tdSendInterval) << " (cfg:" << m_CongCtl->pktSndPeriod_us() << "us) cgwindow=" - << sfmt(cgwindow, sfmc().precision(3))); + << fmt(cgwindow, setprecision(3))); #endif } @@ -8418,7 +8418,7 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ // included, but it also triggers for any other kind of invalid value. // This check MUST BE DONE before making any operation on this number. LOGC(inlog.Error, log << CONID() << "ACK: IPE/EPE: received invalid ACK value: " << ackdata_seqno - << " " << sfmt(ackdata_seqno, "x") << " (IGNORED)"); + << " " << fmt(ackdata_seqno, hex) << " (IGNORED)"); return; } diff --git a/srtcore/logging.cpp b/srtcore/logging.cpp index e76e6db9a..1c51821e2 100644 --- a/srtcore/logging.cpp +++ b/srtcore/logging.cpp @@ -51,7 +51,7 @@ void LogDispatcher::CreateLogLinePrefix(srt::obufstream& serr) SRT_STATIC_ASSERT(ThreadName::BUFSIZE >= sizeof("hh:mm:ss.") * 2, // multiply 2 for some margin "ThreadName::BUFSIZE is too small to be used for strftime"); char tmp_buf[ThreadName::BUFSIZE]; - if ( !isset(SRT_LOGF_DISABLE_TIME) ) + if (!isset(SRT_LOGF_DISABLE_TIME)) { // Not necessary if sending through the queue. timeval tv; @@ -60,25 +60,23 @@ void LogDispatcher::CreateLogLinePrefix(srt::obufstream& serr) if (strftime(tmp_buf, sizeof(tmp_buf), "%X.", &tm)) { - serr << tmp_buf << srt::sfmt(tv.tv_usec, "06"); + serr << tmp_buf << fmt(tv.tv_usec, setfill('0'), setw(6)); } } - string out_prefix; - if ( !isset(SRT_LOGF_DISABLE_SEVERITY) ) - { - out_prefix = prefix; - } - // Note: ThreadName::get needs a buffer of size min. ThreadName::BUFSIZE - if ( !isset(SRT_LOGF_DISABLE_THREADNAME) && ThreadName::get(tmp_buf) ) + if (!isset(SRT_LOGF_DISABLE_THREADNAME) && ThreadName::get(tmp_buf)) { - serr << "/" << tmp_buf << out_prefix << ": "; + serr << "/" << tmp_buf; } - else + + if (!isset(SRT_LOGF_DISABLE_SEVERITY)) { - serr << out_prefix << ": "; + //serr << prefix; + serr.write(prefix, prefix_len); // include terminal 0 } + + serr << ": "; } std::string LogDispatcher::Proxy::ExtractName(std::string pretty_function) diff --git a/srtcore/logging.h b/srtcore/logging.h index cefa5b7ce..3e8dfd07f 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -28,7 +28,7 @@ written by #include #endif -#include "srt_sfmt.h" +//#include "srt_sfmt.h" #include "srt.h" #include "utilities.h" @@ -148,6 +148,7 @@ struct SRT_API LogDispatcher LogLevel::type level; static const size_t MAX_PREFIX_SIZE = 32; char prefix[MAX_PREFIX_SIZE+1]; + size_t prefix_len; LogConfig* src_config; bool isset(int flg) { return (src_config->flags & flg) != 0; } @@ -160,30 +161,30 @@ struct SRT_API LogDispatcher level(log_level), src_config(&config) { - // XXX stpcpy desired, but not enough portable - // Composing the exact prefix is not critical, so simply - // cut the prefix, if the length is exceeded - - // See Logger::Logger; we know this has normally 2 characters, - // except !!FATAL!!, which has 9. Still less than 32. - // If the size of the FA name together with severity exceeds the size, - // just skip the former. - if (logger_pfx && strlen(prefix) + strlen(logger_pfx) + 1 < MAX_PREFIX_SIZE) + size_t your_pfx_len = your_pfx ? strlen(your_pfx) : 0; + size_t logger_pfx_len = logger_pfx ? strlen(logger_pfx) : 0; + + if (logger_pfx && your_pfx_len + logger_pfx_len + 1 < MAX_PREFIX_SIZE) { -#if defined(_MSC_VER) && _MSC_VER < 1900 - _snprintf(prefix, MAX_PREFIX_SIZE, "%s:%s", your_pfx, logger_pfx); -#else - snprintf(prefix, MAX_PREFIX_SIZE + 1, "%s:%s", your_pfx, logger_pfx); -#endif + memcpy(prefix, your_pfx, your_pfx_len); + prefix[your_pfx_len] = ':'; + memcpy(prefix + your_pfx_len + 1, logger_pfx, logger_pfx_len); + prefix[your_pfx_len + logger_pfx_len + 1] = '\0'; + prefix_len = your_pfx_len + logger_pfx_len + 1; + } + else if (your_pfx) + { + // Prefix too long, so copy only your_pfx and only + // as much as it fits + size_t copylen = std::min(+MAX_PREFIX_SIZE, your_pfx_len); + memcpy(prefix, your_pfx, copylen); + prefix[copylen] = '\0'; + prefix_len = copylen; } else { -#ifdef _MSC_VER - strncpy_s(prefix, MAX_PREFIX_SIZE + 1, your_pfx, _TRUNCATE); -#else - strncpy(prefix, your_pfx, MAX_PREFIX_SIZE); - prefix[MAX_PREFIX_SIZE] = '\0'; -#endif + prefix[0] = '\0'; + prefix_len = 0; } } @@ -522,7 +523,8 @@ inline void LogDispatcher::SendLogLine(const char* file, int line, const std::st } else if ( src_config->log_stream ) { - (*src_config->log_stream) << msg; + //(*src_config->log_stream) << msg; + src_config->log_stream->write(msg.data(), msg.size()); (*src_config->log_stream).flush(); } src_config->unlock(); diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp index 43f7349fc..a5dfde68d 100644 --- a/srtcore/queue.cpp +++ b/srtcore/queue.cpp @@ -1079,7 +1079,7 @@ bool srt::CRendezvousQueue::qualifyToHandle(EReadStatus rst, { HLOGC(cnlog.Debug, log << "RID: socket @" << i->m_iID << " still active (remaining " - << sfmt(count_microseconds(i->m_tsTTL - tsNow) / 1000000.0, "f") << "s of TTL)..."); + << fmt(count_microseconds(i->m_tsTTL - tsNow) / 1000000.0, fixed) << "s of TTL)..."); } const steady_clock::time_point tsLastReq = i->m_pUDT->m_tsLastReqTime; diff --git a/srtcore/socketconfig.cpp b/srtcore/socketconfig.cpp index 6d1acf754..955a9006d 100644 --- a/srtcore/socketconfig.cpp +++ b/srtcore/socketconfig.cpp @@ -744,8 +744,8 @@ struct CSrtConfigSetter { co.uKmPreAnnouncePkt = (km_refresh - 1) / 2; LOGC(aclog.Warn, - log << "SRTO_KMREFRESHRATE=0x" << sfmt(km_refresh, "x") << ": setting SRTO_KMPREANNOUNCE=0x" - << sfmt(co.uKmPreAnnouncePkt, "x")); + log << "SRTO_KMREFRESHRATE=0x" << fmt(km_refresh, std::hex) << ": setting SRTO_KMPREANNOUNCE=0x" + << fmt(co.uKmPreAnnouncePkt, std::hex)); } } }; @@ -770,8 +770,8 @@ struct CSrtConfigSetter if (km_preanno > (kmref - 1) / 2) { LOGC(aclog.Error, - log << "SRTO_KMPREANNOUNCE=0x" << sfmt(km_preanno, "x") - << " exceeds KmRefresh/2, 0x" << sfmt((kmref - 1) / 2, "x") + log << "SRTO_KMPREANNOUNCE=0x" << fmt(km_preanno, std::hex) + << " exceeds KmRefresh/2, 0x" << fmt((kmref - 1) / 2, std::hex) << " - OPTION REJECTED."); throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); } diff --git a/srtcore/srt_sfmt.h b/srtcore/srt_sfmt.h index e11b0b730..c4c096852 100644 --- a/srtcore/srt_sfmt.h +++ b/srtcore/srt_sfmt.h @@ -797,6 +797,12 @@ class obufstream return *this; } + obufstream& write(const char* t, size_t size) + { + buffer.append(t, size); + return *this; + } + // For unusual manipulation, usually to add NUL termination. // NOTE: you must make sure that you won't use the extended // buffers if the intention was to get a string. diff --git a/srtcore/sync.cpp b/srtcore/sync.cpp index ff7473ca3..af193c603 100644 --- a/srtcore/sync.cpp +++ b/srtcore/sync.cpp @@ -55,11 +55,11 @@ std::string FormatTime(const steady_clock::time_point& timestamp) if (days) out << days << "D "; - out << srt::sfmt(hours, "02") << ":" - << srt::sfmt(minutes, "02") << ":" - << srt::sfmt(seconds, "02") << "." - << srt::sfmt(frac.time_since_epoch().count(), - srt::sfmc().fillzero().width(decimals)) + out << srt::fmt(hours, setfill('0'), setw(2)) << ":" + << srt::fmt(minutes, setfill('0'), setw(2)) << ":" + << srt::fmt(seconds, setfill('0'), setw(2)) << "." + << srt::fmt(frac.time_since_epoch().count(), + setfill('0'), setw(decimals)) << " [STDY]"; return out.str(); } @@ -77,7 +77,9 @@ std::string FormatTimeSys(const steady_clock::time_point& timestamp) strftime(tmp_buf, 512, "%X.", &tm); srt::obufstream out; - out << tmp_buf << srt::sfmt(count_microseconds(timestamp.time_since_epoch()) % 1000000, "06") << " [SYST]"; + out << tmp_buf + << srt::fmt(count_microseconds(timestamp.time_since_epoch()) % 1000000, setfill('0'), setw(6)) + << " [SYST]"; return out.str(); } diff --git a/srtcore/utilities.h b/srtcore/utilities.h index d7f353765..f85d5b23f 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -567,6 +567,61 @@ namespace any_op } } +// XXX Consider this whole file to be namespace srt! +namespace srt +{ +class fmt_sender_proxy +{ + std::stringstream os; + +public: + + template + explicit fmt_sender_proxy(const TYPE& v, const Args&... manips) + { + manipulate(manips...); + os << v; + } + + void manipulate() {} + + template + void manipulate(const Arg1& manip, const Args&... manips) + { + os << manip; + manipulate(manips...); + } + + template + fmt_sender_proxy& operator *(const OUTER& p) + { + os << p; + return *this; + } + + template + void sendto(OUTSTR& stream) const + { + stream << os.rdbuf(); + } + + operator std::string() const { return os.str(); } +}; + +template +inline fmt_sender_proxy fmt(const TYPE& val, const Args&... manips) +{ + return fmt_sender_proxy(val, manips...); +} + +template +inline TR& operator<<(TR& ot, const fmt_sender_proxy& formatter) +{ + formatter.sendto(ot); + return ot; +} +} + #if HAVE_CXX11 template @@ -673,16 +728,7 @@ class UniquePtr: public std::auto_ptr template inline std::string Sprint(const Arg1& arg) { - return srt::sfmts(arg); -} - -// Ok, let it be 2-arg, in case when a manipulator is needed -template -inline std::string Sprint(const Arg1& arg1, const Arg2& arg2) -{ - srt::obufstream sout; - sout << arg1 << arg2; - return sout.str(); + return fmt_sender_proxy(arg).str(); } template @@ -715,7 +761,8 @@ typename Map::mapped_type const* map_getp(const Map& m, const Key& key) #endif -template inline +#if 0 +template inline std::string Printable(const Container& in, Value /*pseudoargument*/, const char* fmt = 0) { srt::obufstream os; @@ -740,14 +787,21 @@ std::string Printable(const Container& in, std::pair/*pseudoargument os << "]"; return os.str(); } - +#endif template inline std::string Printable(const Container& in) { using namespace srt_pair_op; typedef typename Container::value_type Value; - return Printable(in, Value()); + + srt::obufstream os; + os << "[ "; + typedef typename Container::const_iterator it_t; + for (it_t i = in.begin(); i != in.end(); ++i) + os << Value(*i) << " "; + os << "]"; + return os.str(); } // Printable with prefix added for every element. From f4088e41ffb531bcd2c2d9ea5890dabd021be7f5 Mon Sep 17 00:00:00 2001 From: Mikolaj Malecki Date: Tue, 25 Jun 2024 13:32:12 +0200 Subject: [PATCH 21/41] Removed the use of sfmt obufstream --- apps/logsupport.cpp | 2 +- apps/uriparser.cpp | 2 +- srtcore/common.cpp | 4 ++-- srtcore/handshake.cpp | 2 +- srtcore/logging.cpp | 6 ++--- srtcore/logging.h | 16 ++++++------- srtcore/utilities.h | 55 ++++++++++++++++++++++++++++++++++--------- 7 files changed, 59 insertions(+), 28 deletions(-) diff --git a/apps/logsupport.cpp b/apps/logsupport.cpp index 86deb1690..16a9332df 100644 --- a/apps/logsupport.cpp +++ b/apps/logsupport.cpp @@ -173,7 +173,7 @@ set SrtParseLogFA(string fa, set* punknown) void ParseLogFASpec(const vector& speclist, string& w_on, string& w_off) { - srt::obufstream son, soff; + ostringstream son, soff; for (auto& s: speclist) { diff --git a/apps/uriparser.cpp b/apps/uriparser.cpp index 7425bca03..87687a621 100644 --- a/apps/uriparser.cpp +++ b/apps/uriparser.cpp @@ -64,7 +64,7 @@ string UriParser::makeUri() prefix = m_proto + "://"; } - srt::obufstream out; + ostringstream out; out << prefix << m_host; if ((m_port == "" || m_port == "0") && m_expect == EXPECT_FILE) diff --git a/srtcore/common.cpp b/srtcore/common.cpp index acef9ee77..1a41cfde1 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -277,12 +277,12 @@ void srt::CIPAddress::pton(sockaddr_any& w_addr, const uint32_t ip[4], const soc } else { - obufstream peeraddr_form; + std::stringstream peeraddr_form; peeraddr_form << fmt(peeraddr16[0], hex, setfill('0'), setw(4)); for (int i = 1; i < 8; ++i) peeraddr_form << ":" << fmt(peeraddr16[i], hex, setfill('0'), setw(4)); - LOGC(inlog.Error, log << "pton: IPE or net error: can't determine IPv4 carryover format: " << peeraddr_form); + LOGC(inlog.Error, log << "pton: IPE or net error: can't determine IPv4 carryover format: " << peeraddr_form.rdbuf()); *target_ipv4_addr = 0; if (peer.family() != AF_INET) { diff --git a/srtcore/handshake.cpp b/srtcore/handshake.cpp index f8f03c84d..c97b4e2a3 100644 --- a/srtcore/handshake.cpp +++ b/srtcore/handshake.cpp @@ -300,7 +300,7 @@ std::string srt::SrtFlagString(int32_t flags) #define LEN(arr) (sizeof (arr)/(sizeof ((arr)[0]))) std::string output; - static std::string namera[] = { "TSBPD-snd", "TSBPD-rcv", "haicrypt", "TLPktDrop", "NAKReport", "ReXmitFlag", "StreamAPI" }; + static std::string namera[] = { "TSBPD-snd", "TSBPD-rcv", "haicrypt", "TLPktDrop", "NAKReport", "ReXmitFlag", "StreamAPI", "FilterCapable" }; size_t i = 0; for (; i < LEN(namera); ++i) diff --git a/srtcore/logging.cpp b/srtcore/logging.cpp index 1c51821e2..bc3ad0eec 100644 --- a/srtcore/logging.cpp +++ b/srtcore/logging.cpp @@ -43,7 +43,7 @@ LogDispatcher::Proxy LogDispatcher::operator()() return Proxy(*this); } -void LogDispatcher::CreateLogLinePrefix(srt::obufstream& serr) +void LogDispatcher::CreateLogLinePrefix(std::ostringstream& serr) { using namespace std; using namespace srt; @@ -67,7 +67,7 @@ void LogDispatcher::CreateLogLinePrefix(srt::obufstream& serr) // Note: ThreadName::get needs a buffer of size min. ThreadName::BUFSIZE if (!isset(SRT_LOGF_DISABLE_THREADNAME) && ThreadName::get(tmp_buf)) { - serr << "/" << tmp_buf; + serr << rawstr("/") << tmp_buf; } if (!isset(SRT_LOGF_DISABLE_SEVERITY)) @@ -76,7 +76,7 @@ void LogDispatcher::CreateLogLinePrefix(srt::obufstream& serr) serr.write(prefix, prefix_len); // include terminal 0 } - serr << ": "; + serr << rawstr(": "); } std::string LogDispatcher::Proxy::ExtractName(std::string pretty_function) diff --git a/srtcore/logging.h b/srtcore/logging.h index 3e8dfd07f..30466badd 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -28,8 +28,6 @@ written by #include #endif -//#include "srt_sfmt.h" - #include "srt.h" #include "utilities.h" #include "threadname.h" @@ -194,7 +192,7 @@ struct SRT_API LogDispatcher bool CheckEnabled(); - void CreateLogLinePrefix(srt::obufstream&); + void CreateLogLinePrefix(std::ostringstream&); void SendLogLine(const char* file, int line, const std::string& area, const std::string& sl); // log.Debug("This is the ", nth, " time"); <--- C++11 only. @@ -287,7 +285,7 @@ struct LogDispatcher::Proxy { LogDispatcher& that; - srt::obufstream os; + std::ostringstream os; // Cache the 'enabled' state in the beginning. If the logging // becomes enabled or disabled in the middle of the log, we don't @@ -380,7 +378,7 @@ struct LogDispatcher::Proxy if (that_enabled) { if ((flags & SRT_LOGF_DISABLE_EOL) == 0) - os << srt::seol; + os << std::endl; that.SendLogLine(i_file, i_line, area, os.str()); } // Needed in destructor? @@ -420,7 +418,7 @@ struct LogDispatcher::Proxy buf[len-1] = '\0'; } - os << buf; + os.write(buf, len); return *this; } }; @@ -474,10 +472,10 @@ inline bool LogDispatcher::CheckEnabled() //extern std::mutex Debug_mutex; -inline void PrintArgs(srt::obufstream&) {} +inline void PrintArgs(std::ostringstream&) {} template -inline void PrintArgs(srt::obufstream& serr, Arg1&& arg1, Args&&... args) +inline void PrintArgs(std::ostringstream& serr, Arg1&& arg1, Args&&... args) { serr << std::forward(arg1); PrintArgs(serr, args...); @@ -485,7 +483,7 @@ inline void PrintArgs(srt::obufstream& serr, Arg1&& arg1, Args&&... args) // Add exceptional handling for sync::atomic template -inline void PrintArgs(srt::obufstream& serr, const srt::sync::atomic& arg1, Args&&... args) +inline void PrintArgs(std::ostringstream& serr, const srt::sync::atomic& arg1, Args&&... args) { serr << arg1.load(); PrintArgs(serr, args...); diff --git a/srtcore/utilities.h b/srtcore/utilities.h index f85d5b23f..e5ef025fd 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -45,8 +45,6 @@ written by #include #include -#include "srt_sfmt.h" - // -------------- UTILITIES ------------------------ // --- ENDIAN --- @@ -485,7 +483,7 @@ class FixedArray void throw_invalid_index(int i) const { - srt::obufstream ss; + std::ostringstream ss; ss << "Index " << i << "out of range"; throw std::runtime_error(ss.str()); } @@ -620,6 +618,38 @@ inline TR& operator<<(TR& ot, const fmt_sender_proxy& formatter) formatter.sendto(ot); return ot; } + +template +struct check_minus_1 +{ + static const size_t value = N - 1; +}; + +template<> +struct check_minus_1<0> +{ +}; + +struct rawstr +{ + const char* d; + size_t s; + + rawstr(const char* dd, size_t ss): d(dd), s(ss) {} + const char* data() const { return d; } + size_t size() const { return s; } + + template + explicit rawstr(const char (&ref)[N]): d(ref), s(check_minus_1::value) {} +}; + +template +Stream& operator<<(Stream& out, rawstr v) +{ + out.write(v.data(), v.size()); + return out; +} + } #if HAVE_CXX11 @@ -642,7 +672,7 @@ inline Stream& Print(Stream& sout, Arg1&& arg1, Args&&... args) template inline std::string Sprint(Args&&... args) { - srt::obufstream sout; + std::ostringstream sout; Print(sout, args...); return sout.str(); } @@ -765,7 +795,7 @@ typename Map::mapped_type const* map_getp(const Map& m, const Key& key) template inline std::string Printable(const Container& in, Value /*pseudoargument*/, const char* fmt = 0) { - srt::obufstream os; + std::ostringstream os; os << "[ "; typedef typename Container::const_iterator it_t; for (it_t i = in.begin(); i != in.end(); ++i) @@ -779,7 +809,7 @@ template inline std::string Printable(const Container& in, std::pair/*pseudoargument*/, const char* fmtk = 0, const char* fmtv = 0) { using namespace srt_pair_op; - srt::obufstream os; + std::ostringstream os; os << "[ "; typedef typename Container::const_iterator it_t; for (it_t i = in.begin(); i != in.end(); ++i) @@ -795,7 +825,7 @@ std::string Printable(const Container& in) using namespace srt_pair_op; typedef typename Container::value_type Value; - srt::obufstream os; + std::ostringstream os; os << "[ "; typedef typename Container::const_iterator it_t; for (it_t i = in.begin(); i != in.end(); ++i) @@ -811,7 +841,7 @@ std::string PrintableMod(const Container& in, const std::string& prefix) { using namespace srt_pair_op; typedef typename Container::value_type Value; - srt::obufstream os; + std::ostringstream os; os << "[ "; for (typename Container::const_iterator y = in.begin(); y != in.end(); ++y) os << prefix << Value(*y) << " "; @@ -1034,11 +1064,14 @@ inline std::string FormatBinaryString(const uint8_t* bytes, size_t size) if ( size == 0 ) return ""; - srt::obufstream os; + using namespace std; + + ostringstream os; + os << setfill('0') << setw(2) << hex << uppercase; for (size_t i = 0; i < size; ++i) { - os << srt::sfmt(bytes[i], "02X"); + os << int(bytes[i]); } return os.str(); } @@ -1204,7 +1237,7 @@ inline std::string BufferStamp(const char* mem, size_t size) } // Convert to hex string - return srt::sfmts(sum, "08X"); + return srt::fmt(sum, setfill('0'), setw(8), hex, uppercase); } template From e48a6cbd05219fd7d63fd8866a18be2986631718 Mon Sep 17 00:00:00 2001 From: Mikolaj Malecki Date: Tue, 25 Jun 2024 15:37:28 +0200 Subject: [PATCH 22/41] Removed named reference to avoid dangling ref warning --- srtcore/logging.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srtcore/logging.h b/srtcore/logging.h index 30466badd..a3c8aaa4e 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -53,7 +53,7 @@ written by { \ srt_logging::LogDispatcher::Proxy log(logdes); \ log.setloc(__FILE__, __LINE__, __FUNCTION__); \ - const srt_logging::LogDispatcher::Proxy& log_prox SRT_ATR_UNUSED = args; \ + { (void)(const srt_logging::LogDispatcher::Proxy&)(args); } \ } // LOGF uses printf-like style formatting. From 2ba12a0b67e993447a937421b99e585149c18776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Tue, 25 Jun 2024 16:01:03 +0200 Subject: [PATCH 23/41] Added lacking include for sstream --- srtcore/utilities.h | 1 + 1 file changed, 1 insertion(+) diff --git a/srtcore/utilities.h b/srtcore/utilities.h index e5ef025fd..4a8e26f18 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -35,6 +35,7 @@ written by #include #include #include +#include #if HAVE_CXX11 #include From f16fed782235e414f30692bca37d9280808ef840 Mon Sep 17 00:00:00 2001 From: Mikolaj Malecki Date: Wed, 26 Jun 2024 12:20:30 +0200 Subject: [PATCH 24/41] Cleaned up previous usage of sfmt facilities --- srtcore/{ => ATTIC}/srt_sfmt.h | 0 srtcore/api.cpp | 4 ++-- srtcore/core.cpp | 4 ++-- srtcore/sync.cpp | 12 ++++++------ srtcore/sync.h | 5 ++--- srtcore/utilities.h | 1 + 6 files changed, 13 insertions(+), 13 deletions(-) rename srtcore/{ => ATTIC}/srt_sfmt.h (100%) diff --git a/srtcore/srt_sfmt.h b/srtcore/ATTIC/srt_sfmt.h similarity index 100% rename from srtcore/srt_sfmt.h rename to srtcore/ATTIC/srt_sfmt.h diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 840ef3acd..7e5a01356 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -231,7 +231,7 @@ string srt::CUDTUnited::CONID(SRTSOCKET sock) if (sock == 0) return ""; - srt::obufstream os; + std::stringstream os; os << "@" << sock << ":"; return os.str(); } @@ -3249,7 +3249,7 @@ bool srt::CUDTUnited::updateListenerMux(CUDTSocket* s, const CUDTSocket* ls) CMultiplexer& m = i->second; #if ENABLE_HEAVY_LOGGING - srt::obufstream that_muxer; + std::stringstream that_muxer; that_muxer << "id=" << m.m_iID << " port=" << m.m_iPort << " ip=" << (m.m_iIPversion == AF_INET ? "v4" : "v6"); #endif diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 9eec4a9ae..ec00c34d2 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -10012,9 +10012,9 @@ int srt::CUDT::checkLazySpawnTsbPdThread() HLOGP(qrlog.Debug, "Spawning Socket TSBPD thread"); #if ENABLE_HEAVY_LOGGING - obufstream buf; + std::stringstream buf; // Take the last 2 ciphers from the socket ID. - string s = sfmts(m_SocketID, "02"); + string s = fmt(m_SocketID, setfill('0'), setw(2)).str(); buf << "SRT:TsbPd:@" << s.substr(s.size()-2, 2); const string thname = buf.str(); #else diff --git a/srtcore/sync.cpp b/srtcore/sync.cpp index af193c603..e2061d2ed 100644 --- a/srtcore/sync.cpp +++ b/srtcore/sync.cpp @@ -51,16 +51,16 @@ std::string FormatTime(const steady_clock::time_point& timestamp) const uint64_t minutes = total_sec / 60 - (days * 24 * 60) - hours * 60; const uint64_t seconds = total_sec - (days * 24 * 60 * 60) - hours * 60 * 60 - minutes * 60; steady_clock::time_point frac = timestamp - seconds_from(total_sec); - srt::obufstream out; + std::stringstream out; if (days) - out << days << "D "; + out << days << rawstr("D "); out << srt::fmt(hours, setfill('0'), setw(2)) << ":" << srt::fmt(minutes, setfill('0'), setw(2)) << ":" << srt::fmt(seconds, setfill('0'), setw(2)) << "." << srt::fmt(frac.time_since_epoch().count(), setfill('0'), setw(decimals)) - << " [STDY]"; + << rawstr(" [STDY]"); return out.str(); } @@ -76,10 +76,10 @@ std::string FormatTimeSys(const steady_clock::time_point& timestamp) char tmp_buf[512]; strftime(tmp_buf, 512, "%X.", &tm); - srt::obufstream out; - out << tmp_buf + std::stringstream out; + out << rawstr(tmp_buf) << srt::fmt(count_microseconds(timestamp.time_since_epoch()) % 1000000, setfill('0'), setw(6)) - << " [SYST]"; + << rawstr(" [SYST]"); return out.str(); } diff --git a/srtcore/sync.h b/srtcore/sync.h index 40584a838..dbdbe7d20 100644 --- a/srtcore/sync.h +++ b/srtcore/sync.h @@ -55,7 +55,6 @@ #include "srt.h" #include "utilities.h" #include "srt_attr_defs.h" -#include "srt_sfmt.h" namespace srt { @@ -775,8 +774,8 @@ struct DurationUnitName template inline std::string FormatDuration(const steady_clock::duration& dur) { - obufstream out; - out << sfmt(DurationUnitName::count(dur), "f") << DurationUnitName::name(); + std::stringstream out; + out << fmt(DurationUnitName::count(dur), std::fixed) << DurationUnitName::name(); return out.str(); } diff --git a/srtcore/utilities.h b/srtcore/utilities.h index 4a8e26f18..c7d8d89ae 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -605,6 +605,7 @@ class fmt_sender_proxy } operator std::string() const { return os.str(); } + std::string str() const { return os.str(); } }; template From a49bdd963b7c03fcf01e89b2f733a5c83804e95f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Thu, 27 Jun 2024 15:12:33 +0200 Subject: [PATCH 25/41] Provided C++03 version of fmt --- srtcore/common.cpp | 4 +- srtcore/congctl.cpp | 2 +- srtcore/core.cpp | 16 +++--- srtcore/logging.cpp | 6 +-- srtcore/logging.h | 3 ++ srtcore/queue.cpp | 2 +- srtcore/socketconfig.cpp | 8 +-- srtcore/sync.cpp | 26 +++++----- srtcore/sync.h | 2 +- srtcore/utilities.h | 103 +++++++++++++++++++++++++++++++++------ 10 files changed, 125 insertions(+), 47 deletions(-) diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 1a41cfde1..707babe42 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -278,9 +278,9 @@ void srt::CIPAddress::pton(sockaddr_any& w_addr, const uint32_t ip[4], const soc else { std::stringstream peeraddr_form; - peeraddr_form << fmt(peeraddr16[0], hex, setfill('0'), setw(4)); + peeraddr_form << (fmt(peeraddr16[0]) << hex << setfill('0') << setw(4)); for (int i = 1; i < 8; ++i) - peeraddr_form << ":" << fmt(peeraddr16[i], hex, setfill('0'), setw(4)); + peeraddr_form << ":" << (fmt(peeraddr16[i]) << hex << setfill('0'), setw(4)); LOGC(inlog.Error, log << "pton: IPE or net error: can't determine IPv4 carryover format: " << peeraddr_form.rdbuf()); *target_ipv4_addr = 0; diff --git a/srtcore/congctl.cpp b/srtcore/congctl.cpp index 012d766b5..f5e6400b0 100644 --- a/srtcore/congctl.cpp +++ b/srtcore/congctl.cpp @@ -595,7 +595,7 @@ class FileCC : public SrtCongestionControlBase { m_dPktSndPeriod = m_dCWndSize / (m_parent->SRTT() + m_iRCInterval); HLOGC(cclog.Debug, log << "FileCC: CHKTIMER, SLOWSTART:OFF, sndperiod=" << m_dPktSndPeriod << "us AS wndsize/(RTT+RCIV) (wndsize=" - << fmt(m_dCWndSize, setprecision(6)) << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); + << (fmt(m_dCWndSize) << setprecision(6)) << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")"); } } else diff --git a/srtcore/core.cpp b/srtcore/core.cpp index ec00c34d2..a353b26c6 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -2107,8 +2107,8 @@ int srt::CUDT::processSrtMsg_HSREQ(const uint32_t *srtdata, size_t bytelen, uint } LOGC(cnlog.Debug, log << "HSREQ/rcv: cmd=" << SRT_CMD_HSREQ << "(HSREQ) len=" << bytelen - << " vers=0x" << fmt(srtdata[SRT_HS_VERSION], hex) - << " opts=0x" << fmt(srtdata[SRT_HS_FLAGS], hex) + << " vers=0x" << (fmt(srtdata[SRT_HS_VERSION]) << hex) + << " opts=0x" << (fmt(srtdata[SRT_HS_FLAGS]) << hex) << " delay=" << SRT_HS_LATENCY_RCV::unwrap(srtdata[SRT_HS_LATENCY])); m_uPeerSrtVersion = srtdata[SRT_HS_VERSION]; @@ -2343,7 +2343,7 @@ int srt::CUDT::processSrtMsg_HSRSP(const uint32_t *srtdata, size_t bytelen, uint m_uPeerSrtFlags = srtdata[SRT_HS_FLAGS]; HLOGC(cnlog.Debug, log << "HSRSP/rcv: Version: " << SrtVersionString(m_uPeerSrtVersion) - << " Flags: SND:" << fmt(m_uPeerSrtFlags, hex, setfill('0'), setw(8)) + << " Flags: SND:" << (fmt(m_uPeerSrtFlags) << hex << setfill('0') << setw(8)) << " (" << SrtFlagString(m_uPeerSrtFlags) << ")"); // Basic version check if (m_uPeerSrtVersion < m_config.uMinimumPeerSrtVersion) @@ -5470,14 +5470,14 @@ void * srt::CUDT::tsbpd(void* param) HLOGC(tslog.Debug, log << self->CONID() << "tsbpd: DROPSEQ: up to seqno %" << CSeqNo::decseq(info.seqno) << " (" << iDropCnt << " packets) playable at " << FormatTime(info.tsbpd_time) << " delayed " - << (timediff_us / 1000) << "." << fmt(timediff_us % 1000, fixed, setfill('0'), setw(3)) << " ms"); + << (timediff_us / 1000) << "." << (fmt(timediff_us % 1000) << fixed << setfill('0') << setw(3)) << " ms"); #endif string why; if (self->frequentLogAllowed(FREQLOGFA_RCV_DROPPED, tnow, (why))) { LOGC(brlog.Warn, log << self->CONID() << "RCV-DROPPED " << iDropCnt << " packet(s). Packet seqno %" << info.seqno << " delayed for " << (timediff_us / 1000) << "." - << fmt(timediff_us % 1000, fixed, setfill('0'), setw(3)) << " ms " << why); + << (fmt(timediff_us % 1000) << fixed << setfill('0') << setw(3)) << " ms " << why); } #if SRT_ENABLE_FREQUENT_LOG_TRACE else @@ -7777,7 +7777,7 @@ bool srt::CUDT::updateCC(ETransmissionEvent evt, const EventVariant arg) HLOGC(rslog.Debug, log << CONID() << "updateCC: updated values from congctl: interval=" << FormatDuration(m_tdSendInterval) << " (cfg:" << m_CongCtl->pktSndPeriod_us() << "us) cgwindow=" - << fmt(cgwindow, setprecision(3))); + << (fmt(cgwindow) << setprecision(3))); #endif } @@ -8418,7 +8418,7 @@ void srt::CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_ // included, but it also triggers for any other kind of invalid value. // This check MUST BE DONE before making any operation on this number. LOGC(inlog.Error, log << CONID() << "ACK: IPE/EPE: received invalid ACK value: " << ackdata_seqno - << " " << fmt(ackdata_seqno, hex) << " (IGNORED)"); + << " " << (fmt(ackdata_seqno) << hex) << " (IGNORED)"); return; } @@ -10014,7 +10014,7 @@ int srt::CUDT::checkLazySpawnTsbPdThread() #if ENABLE_HEAVY_LOGGING std::stringstream buf; // Take the last 2 ciphers from the socket ID. - string s = fmt(m_SocketID, setfill('0'), setw(2)).str(); + string s = (fmt(m_SocketID) << setfill('0') << setw(2)).str(); buf << "SRT:TsbPd:@" << s.substr(s.size()-2, 2); const string thname = buf.str(); #else diff --git a/srtcore/logging.cpp b/srtcore/logging.cpp index bc3ad0eec..9a18666eb 100644 --- a/srtcore/logging.cpp +++ b/srtcore/logging.cpp @@ -60,14 +60,14 @@ void LogDispatcher::CreateLogLinePrefix(std::ostringstream& serr) if (strftime(tmp_buf, sizeof(tmp_buf), "%X.", &tm)) { - serr << tmp_buf << fmt(tv.tv_usec, setfill('0'), setw(6)); + serr << tmp_buf << (fmt(tv.tv_usec) << setfill('0') << setw(6)); } } // Note: ThreadName::get needs a buffer of size min. ThreadName::BUFSIZE if (!isset(SRT_LOGF_DISABLE_THREADNAME) && ThreadName::get(tmp_buf)) { - serr << rawstr("/") << tmp_buf; + serr << SRTRSTR("/") << tmp_buf; } if (!isset(SRT_LOGF_DISABLE_SEVERITY)) @@ -76,7 +76,7 @@ void LogDispatcher::CreateLogLinePrefix(std::ostringstream& serr) serr.write(prefix, prefix_len); // include terminal 0 } - serr << rawstr(": "); + serr << SRTRSTR(": "); } std::string LogDispatcher::Proxy::ExtractName(std::string pretty_function) diff --git a/srtcore/logging.h b/srtcore/logging.h index a3c8aaa4e..1763a8328 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -336,6 +336,9 @@ struct LogDispatcher::Proxy return *this; } + // Provide explicit overloads for const char* and string + // so that printing them bypasses the formatting facility + // Special case for atomics, as passing them to snprintf() call // requires unpacking the real underlying value. template diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp index a5dfde68d..20e2ab363 100644 --- a/srtcore/queue.cpp +++ b/srtcore/queue.cpp @@ -1079,7 +1079,7 @@ bool srt::CRendezvousQueue::qualifyToHandle(EReadStatus rst, { HLOGC(cnlog.Debug, log << "RID: socket @" << i->m_iID << " still active (remaining " - << fmt(count_microseconds(i->m_tsTTL - tsNow) / 1000000.0, fixed) << "s of TTL)..."); + << (fmt(count_microseconds(i->m_tsTTL - tsNow) / 1000000.0) << fixed) << "s of TTL)..."); } const steady_clock::time_point tsLastReq = i->m_pUDT->m_tsLastReqTime; diff --git a/srtcore/socketconfig.cpp b/srtcore/socketconfig.cpp index 955a9006d..7e2faa865 100644 --- a/srtcore/socketconfig.cpp +++ b/srtcore/socketconfig.cpp @@ -744,8 +744,8 @@ struct CSrtConfigSetter { co.uKmPreAnnouncePkt = (km_refresh - 1) / 2; LOGC(aclog.Warn, - log << "SRTO_KMREFRESHRATE=0x" << fmt(km_refresh, std::hex) << ": setting SRTO_KMPREANNOUNCE=0x" - << fmt(co.uKmPreAnnouncePkt, std::hex)); + log << "SRTO_KMREFRESHRATE=0x" << (fmt(km_refresh) << std::hex) << ": setting SRTO_KMPREANNOUNCE=0x" + << (fmt(co.uKmPreAnnouncePkt) << std::hex)); } } }; @@ -770,8 +770,8 @@ struct CSrtConfigSetter if (km_preanno > (kmref - 1) / 2) { LOGC(aclog.Error, - log << "SRTO_KMPREANNOUNCE=0x" << fmt(km_preanno, std::hex) - << " exceeds KmRefresh/2, 0x" << fmt((kmref - 1) / 2, std::hex) + log << "SRTO_KMPREANNOUNCE=0x" << (fmt(km_preanno) << std::hex) + << " exceeds KmRefresh/2, 0x" << (fmt((kmref - 1) / 2) << std::hex) << " - OPTION REJECTED."); throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); } diff --git a/srtcore/sync.cpp b/srtcore/sync.cpp index e2061d2ed..34de6586c 100644 --- a/srtcore/sync.cpp +++ b/srtcore/sync.cpp @@ -53,14 +53,13 @@ std::string FormatTime(const steady_clock::time_point& timestamp) steady_clock::time_point frac = timestamp - seconds_from(total_sec); std::stringstream out; if (days) - out << days << rawstr("D "); - - out << srt::fmt(hours, setfill('0'), setw(2)) << ":" - << srt::fmt(minutes, setfill('0'), setw(2)) << ":" - << srt::fmt(seconds, setfill('0'), setw(2)) << "." - << srt::fmt(frac.time_since_epoch().count(), - setfill('0'), setw(decimals)) - << rawstr(" [STDY]"); + out << days << SRTRSTR("D "); + + out << (srt::fmt(hours) << setfill('0') << setw(2)) << SRTRSTR(":") + << (srt::fmt(minutes) << setfill('0'), setw(2)) << SRTRSTR(":") + << (srt::fmt(seconds) << setfill('0'), setw(2)) << SRTRSTR(".") + << (srt::fmt(frac.time_since_epoch().count()) << setfill('0') << setw(decimals)) + << SRTRSTR(" [STDY]"); return out.str(); } @@ -74,12 +73,15 @@ std::string FormatTimeSys(const steady_clock::time_point& timestamp) const time_t tt = now_s + delta_s; struct tm tm = SysLocalTime(tt); // in seconds char tmp_buf[512]; - strftime(tmp_buf, 512, "%X.", &tm); + size_t tmp_size = strftime(tmp_buf, 512, "%X.", &tm); + // Mind the theoretically possible erro case + if (!tmp_size) + return "