• posix quic event epoll


    gdb) bt
    #0  posix_quic::Event::Trigger (event=4, this=0x839080) at /root/posix_quic/src/event.cpp:55
    #1  posix_quic::Event::SetWritable (this=this@entry=0x839080, b=b@entry=true) at /root/posix_quic/src/event.cpp:117
    #2  0x0000000000416660 in posix_quic::QuicSocketEntry::OnCryptoHandshakeComplete (this=0x839080) at /root/posix_quic/src/socket_entry.cpp:457
    #3  0x00000000004cb940 in net::QuicCryptoClientHandshaker::DoReceiveSHLO(net::CryptoHandshakeMessage const*, net::QuicCryptoClientConfig::CachedState*) ()
    #4  0x00000000004cc1c8 in net::QuicCryptoClientHandshaker::DoHandshakeLoop(net::CryptoHandshakeMessage const*) ()
    #5  0x00000000004cc95c in net::QuicCryptoClientHandshaker::OnHandshakeMessage(net::CryptoHandshakeMessage const&) ()
    #6  0x000000000048bf1c in net::CryptoFramer::Process(base::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, net::Perspective) ()
    #7  0x000000000048c70c in net::CryptoFramer::ProcessInput(base::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, net::Perspective) ()
    Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    class QuicEpollerEntry : public FdBase
    {
    public:
        struct quic_epoll_event {
            short int events;
            short int revents;
            epoll_data_t data;
        };
    
        typedef std::unordered_map<
                    int,
                    std::pair<EntryWeakPtr, std::shared_ptr<quic_epoll_event>>
                > FdContainer;
    
        // 引用计数
        typedef std::unordered_map<int, long> UdpContainer;
    
        struct EpollTrigger : public Event::EventTrigger
        {
            QuicEpollerEntry * epollEntry;
    
            void OnTrigger(short int event) override;
            void OnClose(Event* ) override;
        };
    int QuicEpollerEntry::AddInner(int fd, struct epoll_event * event)
    {
        std::unique_lock<std::mutex> lock(mtx_);
        auto itr = fds_.find(fd);
        if (itr != fds_.end()) {
            EntryPtr entry = itr->second.first.lock();
            if (entry && entry->Fd() == fd) {
                errno = EEXIST;
                return -1;
            }
    
            fds_.erase(itr);
        }
    
        EntryPtr entry = EntryBase::GetFdManager().Get(fd);
        if (!entry || entry->Fd() != fd) {
            errno = EBADF;
            return -1;
        }
    
        std::shared_ptr<quic_epoll_event> qev(new quic_epoll_event);
        qev->events = Epoll2Poll(event->events);
        qev->data = event->data;
        qev->revents = 0;
    
        Event::EventWaiter waiter = { &qev->events, &qev->revents };
        if (!entry->StartWait(waiter, &trigger_)) {
            errno = EBADF;
            return -1;
        }
    
        fds_[fd] = std::make_pair(EntryWeakPtr(entry), qev);
    
        // listen udp
        std::shared_ptr<int> udpSocket = entry->NativeUdpFd();
        if (!udpSocket) {
            // QuicSocket必须已经有了对应的udp socket才能加入Epoller.
            // 自行创建的QuicSocket, Bind后就可以了.
            entry->StopWait(&trigger_);
            errno = EINVAL;
            return -1;
        }
    
        if (entry->Category() == EntryCategory::Socket) {
            if (!((QuicSocketEntry*)entry.get())->GetQuicTaskRunnerProxy()->Link(&taskRunner_)) {
                entry->StopWait(&trigger_);
                errno = EBUSY;
                return -1;
            }
        }
    
        auto udpItr = udps_.find(*udpSocket);
        if (udps_.end() == udpItr) {
            struct epoll_event udpEv;
            udpEv.events = EPOLLIN;
            udpEv.data.fd = *udpSocket;
            int res = epoll_ctl(Fd(), EPOLL_CTL_ADD, *udpSocket, &udpEv);
            if (res < 0) {
                return -1;
            }
            udps_[*udpSocket] = 1;
    
            DebugPrint(dbg_epoll, "Add udp socket = %d, quicFd = %d", *udpSocket, fd);
        } else {
            udpItr->second++;
            DebugPrint(dbg_epoll, "Ref udp socket = %d, quicFd = %d", *udpSocket, fd);
        }
    
        return 0;
    (gdb) bt
    #0  posix_quic::QuicEpollerEntry::AddInner (this=this@entry=0x835950, fd=fd@entry=2, event=event@entry=0xffffffff90b8) at /root/posix_quic/src/epoller_entry.cpp:115
    #1  0x0000000000408a40 in posix_quic::QuicEpollerEntry::Add (this=this@entry=0x835950, fd=fd@entry=2, event=event@entry=0xffffffff90b8) at /root/posix_quic/src/epoller_entry.cpp:110
    #2  0x00000000004155d8 in posix_quic::QuicEpollCtl (epfd=3, epfd@entry=3224376, op=op@entry=1, quicFd=quicFd@entry=2, event=0xffffffff90b8, event@entry=0xffffffff9148) at /root/posix_quic/src/quic_socket.cpp:462
    #3  0x00000000004020e0 in doLoop (ep=3224376, ep@entry=3) at /root/posix_quic/test/client/src/client.cpp:61
    #4  0x00000000004009c8 in main () at /root/posix_quic/test/client/src/client.cpp:149

    udp socket

    Thread 1 "client" hit Breakpoint 1, doLoop (ep=3749433, ep@entry=3) at /root/posix_quic/test/client/src/client.cpp:61
    61                      res = QuicEpollCtl(ep, EPOLL_CTL_ADD, stream, &ev);
    (gdb) p stream
    $1 = 2
    (gdb) p fd
    $2 = 1
    (gdb) s
    59                      ev.events = EPOLLIN;
    (gdb) list
    54                      QuicStream stream = QuicCreateStream(fd);
    55                      assert(stream > 0);
    56
    57                      struct epoll_event ev;
    58                      ev.data.fd = stream;
    59                      ev.events = EPOLLIN;
    60                      //res = QuicEpollCtl(ep, EPOLL_CTL_MOD, stream, &ev);
    61                      res = QuicEpollCtl(ep, EPOLL_CTL_ADD, stream, &ev);
    62                      CHECK_RES(res, "epoll_ctl");
    63
    (gdb) b /epoller_entry.cpp:148
    No source file named /epoller_entry.cpp.
    Make breakpoint pending on future shared library load? (y or [n]) y
    Breakpoint 2 (/epoller_entry.cpp:148) pending.
    (gdb) b epoller_entry.cpp:148
    Breakpoint 3 at 0x4083e8: file /root/posix_quic/src/epoller_entry.cpp, line 148.
    (gdb) c
    Continuing.
    
    Thread 1 "client" hit Breakpoint 3, posix_quic::QuicEpollerEntry::AddInner (this=this@entry=0x835950, fd=1718229288, fd@entry=2, event=event@entry=0xffffffff90b8) at /root/posix_quic/src/epoller_entry.cpp:148
    148         std::shared_ptr<int> udpSocket = entry->NativeUdpFd();
    (gdb) n
    149         if (!udpSocket) {
    (gdb) p *udpSocket
    Could not find operator*.
    (gdb) p udpSocket->get()
    Could not find operator->.
    (gdb) p udpSocket
    $3 = {<std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>> = {_M_ptr = 0x839350, _M_refcount = {_M_pi = 0x839370}}, <No data fields>}
    (gdb) p *(0x839350)
    $4 = 7   //udp socket 的句柄
    (gdb) p *(0x839350)

    QuicEpollerEntry::Poll

    (gdb) bt
    #0  posix_quic::QuicEpollerEntry::Poll (this=this@entry=0x835950, events=0xffffffff9108, events@entry=0x41ef58 <posix_quic::QuicStreamEntry::GetQuartcStream()+128>, maxevents=1024, maxevents@entry=65535) at /root/posix_quic/src/epoller_entry.cpp:385
    #1  0x0000000000406544 in posix_quic::QuicEpollerEntry::Wait (this=this@entry=0x835950, events=0x41ef58 <posix_quic::QuicStreamEntry::GetQuartcStream()+128>, events@entry=0xffffffff9108, maxevents=65535, maxevents@entry=1024, 
        timeout=timeout@entry=6000) at /root/posix_quic/src/epoller_entry.cpp:263
    #2  0x000000000041586c in posix_quic::QuicEpollWait (epfd=3, epfd@entry=3749376, events=events@entry=0xffffffff9108, maxevents=maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/quic_socket.cpp:494
    #3  0x0000000000401dfc in doLoop (ep=3749376, ep@entry=3) at /root/posix_quic/test/client/src/client.cpp:37
    #4  0x00000000004009c8 in main () at /root/posix_quic/test/client/src/client.cpp:149
    (gdb) 
    int QuicEpollerEntry::Poll(struct epoll_event *events, int maxevents)
    {
        std::unique_lock<std::mutex> lock(mtx_);
        int i = 0;
        for (auto & kv : fds_) {
            if (i >= maxevents) break;
    
            quic_epoll_event & qev = *(kv.second.second);
            short int event = qev.events | POLLERR;
    
    //        DebugPrint(dbg_event, "fd = %d, qev.revents = %s, event = %s",
    //                kv.first, PollEvent2Str(qev.revents), PollEvent2Str(event));
    
            short int revents = __atomic_fetch_and(&qev.revents, ~event, std::memory_order_seq_cst);
            revents &= event;
    
            DebugPrint(dbg_event, "after __atomic_fetch_and fd = %d, qev.revents = %s, revents = %s",
                    kv.first, PollEvent2Str(qev.revents), PollEvent2Str(revents));
    
            if (revents == 0) continue;
    
            struct epoll_event & ev = events[i++];
            ev.data = qev.data;
            ev.events = Poll2Epoll(revents);
        }
    
        DebugPrint(dbg_epoll, "QuicEpollerEntry::Poll returns %d", i);
        return i;
    }

     

    Event::EventTrigger::Trigger  & wait

    void Event::EventTrigger::Trigger(short int event)
    {
        {
            std::unique_lock<std::mutex> lock(cvMtx);
            triggered = true;
            cv.notify_one(); //条件变量
        }
    
        OnTrigger(event);
    }
     

    Thread 1 "client" hit Breakpoint 1, posix_quic::Event::TriggerWithoutLock (event=4, this=0x839080) at /root/posix_quic/src/event.cpp:82
    82                          trigger->Trigger(POLLOUT);
    (gdb) bt
    #0  posix_quic::Event::TriggerWithoutLock (event=4, this=0x839080) at /root/posix_quic/src/event.cpp:82
    #1  posix_quic::Event::Trigger (event=4, this=0x839080) at /root/posix_quic/src/event.cpp:55
    #2  posix_quic::Event::SetWritable (this=this@entry=0x839080, b=b@entry=true) at /root/posix_quic/src/event.cpp:117
    #3  0x00000000004166a0 in posix_quic::QuicSocketEntry::OnCryptoHandshakeComplete (this=0x839080) at /root/posix_quic/src/socket_entry.cpp:457
    #4  0x00000000004ca980 in net::QuicCryptoClientHandshaker::DoReceiveSHLO(net::CryptoHandshakeMessage const*, net::QuicCryptoClientConfig::CachedState*) ()
    #5  0x00000000004cb208 in net::QuicCryptoClientHandshaker::DoHandshakeLoop(net::CryptoHandshakeMessage const*) ()
    #6  0x00000000004cb99c in net::QuicCryptoClientHandshaker::OnHandshakeMessage(net::CryptoHandshakeMessage const&) ()
    #7  0x000000000048af5c in net::CryptoFramer::Process(base::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, net::Perspective) ()
    #8  0x000000000048b74c in net::CryptoFramer::ProcessInput(base::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, net::Perspective) ()
    Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    (gdb) c
    Continuing.
    [16:35:54.777784]client.cpp:47:(doLoop) [C=0]    QuicEpoller trigger: fd = 1, category = Socket, events = EPOLLOUT
    [16:35:54.777874]client.cpp:51:(doLoop) [C=0]    Connected.
    
    
    Thread 1 "client" hit Breakpoint 1, posix_quic::Event::TriggerWithoutLock (event=1, this=0x84bbc0) at /root/posix_quic/src/event.cpp:71
    71                          trigger->Trigger(POLLIN);
    (gdb) bt
    #0  posix_quic::Event::TriggerWithoutLock (event=1, this=0x84bbc0) at /root/posix_quic/src/event.cpp:71
    #1  posix_quic::Event::Trigger (event=1, this=0x84bbc0) at /root/posix_quic/src/event.cpp:55
    #2  posix_quic::Event::SetReadable (this=this@entry=0x84bbc0, b=b@entry=true) at /root/posix_quic/src/event.cpp:111
    #3  0x000000000041e9dc in posix_quic::QuicStreamEntry::OnReceived (this=0x84bbc0, stream=<optimized out>, data=0x853970 "Hello quic!", size=11) at /root/posix_quic/src/stream_entry.cpp:152
    #4  0x0000000000465494 in net::QuartcStream::OnDataAvailable() ()
    #5  0x000000000045696c in net::QuicStreamSequencer::OnStreamFrame(net::QuicStreamFrame const&) ()
    #6  0x0000000000450bb8 in net::QuicStream::OnStreamFrame(net::QuicStreamFrame const&) ()
    #7  0x000000000044cb14 in net::QuicSession::OnStreamFrame(net::QuicStreamFrame const&) ()
    #8  0x000000000043210c in net::QuicConnection::OnStreamFrame(net::QuicStreamFrame const&) ()
    #9  0x000000000043fd64 in net::QuicFramer::ProcessFrameData(net::QuicDataReader*, net::QuicPacketHeader const&) [clone .part.162] [clone .constprop.172] ()
    #10 0x00000000004402f8 in net::QuicFramer::ProcessDataPacket(net::QuicDataReader*, net::QuicPacketHeader*, net::QuicEncryptedPacket const&, char*, unsigned long) [clone .part.163] [clone .constprop.166] ()
    #11 0x0000000000440724 in net::QuicFramer::ProcessPacket(net::QuicEncryptedPacket const&) ()
    #12 0x00000000004349f8 in net::QuicConnection::ProcessUdpPacket(net::QuicSocketAddress const&, net::QuicSocketAddress const&, net::QuicReceivedPacket const&) ()
    #13 0x0000000000417298 in posix_quic::QuicSocketEntry::ProcessUdpPacket (this=this@entry=0x839080, self_address=..., peer_address=..., packet=...) at /root/posix_quic/src/socket_entry.cpp:415
    #14 0x0000000000407090 in posix_quic::QuicEpollerEntry::Wait (this=this@entry=0x835950, events=0x461830 <net::QuicSocketAddressImpl::QuicSocketAddressImpl(sockaddr_storage const&)+48>, events@entry=0xffffffff9118, maxevents=65535, 
        maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/epoller_entry.cpp:376
    #15 0x000000000041586c in posix_quic::QuicEpollWait (epfd=3, epfd@entry=3421952, events=events@entry=0xffffffff9118, maxevents=maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/quic_socket.cpp:494
    #16 0x0000000000401dfc in doLoop (ep=3421952, ep@entry=3) at /root/posix_quic/test/client/src/client.cpp:37
    #17 0x00000000004009c8 in main () at /root/posix_quic/test/client/src/client.cpp:149
    (gdb) c
    (gdb) bt
    #0  posix_quic::Event::TriggerWithoutLock (event=8, this=0x84bbc0) at /root/posix_quic/src/event.cpp:92
    #1  posix_quic::Event::Trigger (event=<optimized out>, this=<optimized out>) at /root/posix_quic/src/event.cpp:55
    #2  posix_quic::Event::SetError (this=0x84bbc0, err=<optimized out>, quicErr=<optimized out>) at /root/posix_quic/src/event.cpp:126
    #3  0x000000000044b704 in net::QuicSession::CloseStreamInner(unsigned int, bool) ()
    #4  0x0000000000465514 in net::QuartcStream::OnDataAvailable() ()
    #5  0x000000000045625c in net::QuicStreamSequencer::MaybeCloseStream() ()
    #6  0x0000000000456400 in net::QuicStreamSequencer::OnStreamFrame(net::QuicStreamFrame const&) ()
    #7  0x0000000000450bb8 in net::QuicStream::OnStreamFrame(net::QuicStreamFrame const&) ()
    #8  0x000000000044cb14 in net::QuicSession::OnStreamFrame(net::QuicStreamFrame const&) ()
    #9  0x000000000043210c in net::QuicConnection::OnStreamFrame(net::QuicStreamFrame const&) ()
    #10 0x000000000043fd64 in net::QuicFramer::ProcessFrameData(net::QuicDataReader*, net::QuicPacketHeader const&) [clone .part.162] [clone .constprop.172] ()
    #11 0x00000000004402f8 in net::QuicFramer::ProcessDataPacket(net::QuicDataReader*, net::QuicPacketHeader*, net::QuicEncryptedPacket const&, char*, unsigned long) [clone .part.163] [clone .constprop.166] ()
    #12 0x0000000000440724 in net::QuicFramer::ProcessPacket(net::QuicEncryptedPacket const&) ()
    #13 0x00000000004349f8 in net::QuicConnection::ProcessUdpPacket(net::QuicSocketAddress const&, net::QuicSocketAddress const&, net::QuicReceivedPacket const&) ()
    #14 0x0000000000417298 in posix_quic::QuicSocketEntry::ProcessUdpPacket (this=this@entry=0x839080, self_address=..., peer_address=..., packet=...) at /root/posix_quic/src/socket_entry.cpp:415
    #15 0x0000000000407090 in posix_quic::QuicEpollerEntry::Wait (this=this@entry=0x835950, events=0x461830 <net::QuicSocketAddressImpl::QuicSocketAddressImpl(sockaddr_storage const&)+48>, events@entry=0xffffffff9118, maxevents=65535, 
        maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/epoller_entry.cpp:376
    #16 0x000000000041586c in posix_quic::QuicEpollWait (epfd=3, epfd@entry=3356724, events=events@entry=0xffffffff9118, maxevents=maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/quic_socket.cpp:494
    #17 0x0000000000401dfc in doLoop (ep=3356724, ep@entry=3) at /root/posix_quic/test/client/src/client.cpp:37
    #18 0x00000000004009c8 in main () at /root/posix_quic/test/client/src/client.cpp:149
    (gdb) c

    QuicEpollerEntry::Notify

    (gdb) b QuicEpollerEntry::Notify
    Breakpoint 1 at 0x404164: QuicEpollerEntry::Notify. (2 locations)
    (gdb) r
    Starting program: /root/posix_quic/test/client/client 
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
    [New Thread 0xffffbf6fe010 (LWP 47445)]
    [New Thread 0xffffbeefd010 (LWP 47446)]
    
    Thread 1 "client" hit Breakpoint 1, posix_quic::QuicEpollerEntry::EpollTrigger::OnTrigger (this=0x835a30, event=4) at /root/posix_quic/src/epoller_entry.cpp:15
    15          epollEntry->Notify();
    (gdb) bt
    #0  posix_quic::QuicEpollerEntry::EpollTrigger::OnTrigger (this=0x835a30, event=4) at /root/posix_quic/src/epoller_entry.cpp:15
    #1  0x000000000040d43c in posix_quic::Event::EventTrigger::Trigger (event=4, this=0x835a30) at /root/posix_quic/src/event.cpp:33
    #2  posix_quic::Event::TriggerWithoutLock (event=4, this=0x839080) at /root/posix_quic/src/event.cpp:82
    #3  posix_quic::Event::Trigger (event=4, this=0x839080) at /root/posix_quic/src/event.cpp:55
    #4  posix_quic::Event::SetWritable (this=this@entry=0x839080, b=b@entry=true) at /root/posix_quic/src/event.cpp:117
    #5  0x00000000004166a0 in posix_quic::QuicSocketEntry::OnCryptoHandshakeComplete (this=0x839080) at /root/posix_quic/src/socket_entry.cpp:457
    #6  0x00000000004ca980 in net::QuicCryptoClientHandshaker::DoReceiveSHLO(net::CryptoHandshakeMessage const*, net::QuicCryptoClientConfig::CachedState*) ()
    #7  0x00000000004cb208 in net::QuicCryptoClientHandshaker::DoHandshakeLoop(net::CryptoHandshakeMessage const*) ()
    #8  0x00000000004cb99c in net::QuicCryptoClientHandshaker::OnHandshakeMessage(net::CryptoHandshakeMessage const&) ()
    #9  0x000000000048af5c in net::CryptoFramer::Process(base::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, net::Perspective) ()
    #10 0x000000000048b74c in net::CryptoFramer::ProcessInput(base::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, net::Perspective) ()
    Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    (gdb) c
    Continuing.
    [Switching to Thread 0xffffbf6fe010 (LWP 47445)]
    
    Thread 2 "client" hit Breakpoint 1, posix_quic::QuicEpollerEntry::Notify (this=0x835950) at /root/posix_quic/src/epoller_entry.cpp:19
    19      {
    (gdb) bt
    #0  posix_quic::QuicEpollerEntry::Notify (this=0x835950) at /root/posix_quic/src/epoller_entry.cpp:19
    #1  0x0000000000406364 in posix_quic::QuicEpollerEntry::<lambda()>::operator() (__closure=<optimized out>) at /root/posix_quic/src/epoller_entry.cpp:60
    #2  std::_Bind_simple<posix_quic::QuicEpollerEntry::QuicEpollerEntry()::<lambda()>()>::_M_invoke<> (this=<optimized out>) at /usr/include/c++/5/functional:1531
    #3  std::_Bind_simple<posix_quic::QuicEpollerEntry::QuicEpollerEntry()::<lambda()>()>::operator() (this=<optimized out>) at /usr/include/c++/5/functional:1520
    #4  std::thread::_Impl<std::_Bind_simple<posix_quic::QuicEpollerEntry::QuicEpollerEntry()::<lambda()>()> >::_M_run(void) (this=0x835f70) at /usr/include/c++/5/thread:115
    #5  0x0000000000652018 in execute_native_thread_routine ()
    #6  0x0000000000603bb0 in start_thread (arg=0xfffffffff64f) at pthread_create.c:463
    #7  0x00000000006f2b7c in thread_start ()
    (gdb) 

    __atomic_fetch_and & __atomic_fetch_or

    void Event::TriggerWithoutLock(short int event)
    {
        for (auto & kv : waitings_) {
            EventTrigger * trigger = kv.first;
            EventWaiter & waiter = kv.second;
            switch (event) {
                case POLLIN:
                    if (*waiter.events & POLLIN) {
                        DebugPrint(dbg_event, "fd = %d, epfd = %d, trigger event = POLLIN. waiter.revents = %s",
                                Fd(), trigger->epollfd, PollEvent2Str(*waiter.revents));
                        __atomic_fetch_or(waiter.revents, POLLIN, std::memory_order_seq_cst);
                        DebugPrint(dbg_event, "fd = %d, epfd = %d, trigger event = POLLIN. waiter.revents = %s",
                                Fd(), trigger->epollfd, PollEvent2Str(*waiter.revents));
                        trigger->Trigger(POLLIN);
                    }
                    break;
    
                case POLLOUT:
                    if (*waiter.events & POLLOUT) {
                        DebugPrint(dbg_event, "fd = %d, epfd = %d, trigger event = POLLOUT. waiter.revents = %s",
                                Fd(), trigger->epollfd, PollEvent2Str(*waiter.revents));
                        __atomic_fetch_or(waiter.revents, POLLOUT, std::memory_order_seq_cst);
                        DebugPrint(dbg_event, "fd = %d, epfd = %d, trigger event = POLLOUT. waiter.revents = %s",
                                Fd(), trigger->epollfd, PollEvent2Str(*waiter.revents));
                        trigger->Trigger(POLLOUT);
                    }
                    break;
    
                case POLLERR:
                    DebugPrint(dbg_event, "fd = %d, epfd = %d, trigger event = POLLERR. waiter.revents = %s",
                            Fd(), trigger->epollfd, PollEvent2Str(*waiter.revents));
                    __atomic_fetch_or(waiter.revents, POLLERR, std::memory_order_seq_cst);
                    DebugPrint(dbg_event, "fd = %d, epfd = %d, trigger event = POLLERR. waiter.revents = %s",
                            Fd(), trigger->epollfd, PollEvent2Str(*waiter.revents));
                    trigger->Trigger(POLLERR);
                    break;
    
                default:
                    break;
            }
        }
    }
    int QuicEpollerEntry::Poll(struct epoll_event *events, int maxevents)
    {
        std::unique_lock<std::mutex> lock(mtx_);
        int i = 0;
        for (auto & kv : fds_) {
            if (i >= maxevents) break;
    
            quic_epoll_event & qev = *(kv.second.second);
            short int event = qev.events | POLLERR;
    
    //        DebugPrint(dbg_event, "fd = %d, qev.revents = %s, event = %s",
    //                kv.first, PollEvent2Str(qev.revents), PollEvent2Str(event));
    
            short int revents = __atomic_fetch_and(&qev.revents, ~event, std::memory_order_seq_cst);
            revents &= event;
    
            DebugPrint(dbg_event, "after __atomic_fetch_and fd = %d, qev.revents = %s, revents = %s",
                    kv.first, PollEvent2Str(qev.revents), PollEvent2Str(revents));
    
            if (revents == 0) continue;
    
            struct epoll_event & ev = events[i++];
            ev.data = qev.data;
            ev.events = Poll2Epoll(revents);
        }
    
        DebugPrint(dbg_epoll, "QuicEpollerEntry::Poll returns %d", i);
        return i;
    }

    SetXXX函数

    void SetReadable(bool b);
        void SetWritable(bool b);
        void SetError(int err, int quicErr = 0);
    void QuartcStream::OnDataAvailable() {
      // Do not deliver data until the entire stream's data is available.
      if (deliver_on_complete_ &&
          sequencer()->ReadableBytes() + sequencer()->NumBytesConsumed() <
              sequencer()->close_offset()) {
        return;
      }
    
      struct iovec iov;
      while (sequencer()->GetReadableRegion(&iov)) {
        DCHECK(delegate_);
        delegate_->OnReceived(this, reinterpret_cast<const char*>(iov.iov_base),
                              iov.iov_len);
        sequencer()->MarkConsumed(iov.iov_len);
      }
      // All the data has been received if the sequencer is closed.
      // Notify the delegate by calling the callback function one more time with
      // iov_len = 0.
      if (sequencer()->IsClosed()) {
        OnFinRead();
        delegate_->OnReceived(this, reinterpret_cast<const char*>(iov.iov_base), 0);
      }
    }
    
    void QuartcStream::OnClose() {
      QuicStream::OnClose();
      DCHECK(delegate_);
      delegate_->OnClose(this);
    }
    
    void QuartcStream::OnStreamDataConsumed(size_t bytes_consumed) {
      QuicStream::OnStreamDataConsumed(bytes_consumed);
    
      DCHECK(delegate_);
      delegate_->OnBufferChanged(this);
    }
    
    void QuartcStream::OnDataBuffered(
        QuicStreamOffset offset,
        QuicByteCount data_length,
        const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener) {
      DCHECK(delegate_);
      delegate_->OnBufferChanged(this);
    }
    
    void QuartcStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
                                                  QuicByteCount data_length,
                                                  bool fin_retransmitted) {
      QuicStream::OnStreamFrameRetransmitted(offset, data_length,
                                             fin_retransmitted);
    
      DCHECK(delegate_);
      delegate_->OnBufferChanged(this);
    }
    
    void QuartcStream::OnStreamFrameLost(QuicStreamOffset offset,
                                         QuicByteCount data_length,
                                         bool fin_lost) {
      QuicStream::OnStreamFrameLost(offset, data_length, fin_lost);
    
      DCHECK(delegate_);
      delegate_->OnBufferChanged(this);
    }

    posix_quic::Event::SetReadable

    (gdb) bt
    #0  posix_quic::Event::TriggerWithoutLock (event=1, this=0x84bbc0) at /root/posix_quic/src/event.cpp:71
    #1  posix_quic::Event::Trigger (event=1, this=0x84bbc0) at /root/posix_quic/src/event.cpp:55
    #2  posix_quic::Event::SetReadable (this=this@entry=0x84bbc0, b=b@entry=true) at /root/posix_quic/src/event.cpp:111
    #3  0x000000000041e9dc in posix_quic::QuicStreamEntry::OnReceived (this=0x84bbc0, stream=<optimized out>, data=0x853970 "Hello quic!", size=11) at /root/posix_quic/src/stream_entry.cpp:152
    #4  0x0000000000465494 in net::QuartcStream::OnDataAvailable() ()
    #5  0x000000000045696c in net::QuicStreamSequencer::OnStreamFrame(net::QuicStreamFrame const&) ()
    #6  0x0000000000450bb8 in net::QuicStream::OnStreamFrame(net::QuicStreamFrame const&) ()
    #7  0x000000000044cb14 in net::QuicSession::OnStreamFrame(net::QuicStreamFrame const&) ()
    #8  0x000000000043210c in net::QuicConnection::OnStreamFrame(net::QuicStreamFrame const&) ()
    #9  0x000000000043fd64 in net::QuicFramer::ProcessFrameData(net::QuicDataReader*, net::QuicPacketHeader const&) [clone .part.162] [clone .constprop.172] ()
    #10 0x00000000004402f8 in net::QuicFramer::ProcessDataPacket(net::QuicDataReader*, net::QuicPacketHeader*, net::QuicEncryptedPacket const&, char*, unsigned long) [clone .part.163] [clone .constprop.166] ()
    #11 0x0000000000440724 in net::QuicFramer::ProcessPacket(net::QuicEncryptedPacket const&) ()
    #12 0x00000000004349f8 in net::QuicConnection::ProcessUdpPacket(net::QuicSocketAddress const&, net::QuicSocketAddress const&, net::QuicReceivedPacket const&) ()
    #13 0x0000000000417298 in posix_quic::QuicSocketEntry::ProcessUdpPacket (this=this@entry=0x839080, self_address=..., peer_address=..., packet=...) at /root/posix_quic/src/socket_entry.cpp:415
    #14 0x0000000000407090 in posix_quic::QuicEpollerEntry::Wait (this=this@entry=0x835950, events=0x461830 <net::QuicSocketAddressImpl::QuicSocketAddressImpl(sockaddr_storage const&)+48>, events@entry=0xffffffff9118, maxevents=65535, 
        maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/epoller_entry.cpp:376
    #15 0x000000000041586c in posix_quic::QuicEpollWait (epfd=3, epfd@entry=3421952, events=events@entry=0xffffffff9118, maxevents=maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/quic_socket.cpp:494
    #16 0x0000000000401dfc in doLoop (ep=3421952, ep@entry=3) at /root/posix_quic/test/client/src/client.cpp:37
    #17 0x00000000004009c8 in main () at /root/posix_quic/test/client/src/client.cpp:149
    (gdb) c

    Event::SetWritable

    (gdb) bt
    #0  0x0000000000462f8c in net::QuartcPacketWriter::SetWritable() ()
    #1  0x0000000000463380 in net::QuartcSession::OnTransportCanWrite() ()
    #2  0x0000000000419f68 in posix_quic::QuicSocketEntry::Connect (this=this@entry=0x839080, addr=addr@entry=0xfffffffff978, addrlen=addrlen@entry=16) at /root/posix_quic/src/socket_entry.cpp:278
    #3  0x0000000000410164 in posix_quic::QuicConnect (sock=sock@entry=1, addr=0xfffffffff978, addr@entry=0xfffffffff998, addrlen=addrlen@entry=16) at /root/posix_quic/src/quic_socket.cpp:98
    #4  0x0000000000400984 in main () at /root/posix_quic/test/client/src/client.cpp:138
    (gdb) c
    Continuing.
    [19:20:10.192801]epoller_entry.cpp:176:(AddInner) [C=0]  Add udp socket = 7, quicFd = 1
    [19:20:10.192889]epoller_entry.cpp:111:(Add) [C=0]       fd = 1, events = EPOLLIN|EPOLLOUT
    [19:20:10.192906]epoller_entry.cpp:257:(Wait) [C=0]      QuicEpollerEntry::Wait begin
    [19:20:10.192977]epoller_entry.cpp:410:(Poll) [C=0]      QuicEpollerEntry::Poll returns 0
    [19:20:10.192994]epoller_entry.cpp:410:(Poll) [C=0]      QuicEpollerEntry::Poll returns 0
    [19:20:10.193004]epoller_entry.cpp:381:(Wait) [C=0]      QuicEpollerEntry::Wait returns 0
    [19:20:10.193014]epoller_entry.cpp:257:(Wait) [C=0]      QuicEpollerEntry::Wait begin
    [19:20:10.193023]epoller_entry.cpp:410:(Poll) [C=0]      QuicEpollerEntry::Poll returns 0
    [19:20:10.193868]epoller_entry.cpp:316:(Wait) [C=0]      syscall -> recvfrom 127.0.0.1:9700. Udp socket = 7, bytes = 1200, errno = 0
    [19:20:10.193887]epoller_entry.cpp:367:(Wait) [C=0]       -> recvfrom. Udp socket = 7, connectionId = 15368493319691896021 is exists.
    [19:20:10.194419]epoller_entry.cpp:316:(Wait) [C=0]      syscall -> recvfrom Uninitialized address. Udp socket = 7, bytes = -1, errno = 11
    [19:20:10.194435]epoller_entry.cpp:410:(Poll) [C=0]      QuicEpollerEntry::Poll returns 0
    [19:20:10.194445]epoller_entry.cpp:381:(Wait) [C=0]      QuicEpollerEntry::Wait returns 0
    [19:20:10.194455]epoller_entry.cpp:257:(Wait) [C=0]      QuicEpollerEntry::Wait begin
    [19:20:10.194464]epoller_entry.cpp:410:(Poll) [C=0]      QuicEpollerEntry::Poll returns 0
    [19:20:10.195023]epoller_entry.cpp:316:(Wait) [C=0]      syscall -> recvfrom 127.0.0.1:9700. Udp socket = 7, bytes = 1200, errno = 0
    [19:20:10.195038]epoller_entry.cpp:367:(Wait) [C=0]       -> recvfrom. Udp socket = 7, connectionId = 15368493319691896021 is exists.
    
    Thread 1 "client" hit Breakpoint 1, posix_quic::Event::SetWritable (this=this@entry=0x839080, b=b@entry=true) at /root/posix_quic/src/event.cpp:114
    114     {
    (gdb) bt
    #0  posix_quic::Event::SetWritable (this=this@entry=0x839080, b=b@entry=true) at /root/posix_quic/src/event.cpp:114
    #1  0x00000000004166a8 in posix_quic::QuicSocketEntry::OnCryptoHandshakeComplete (this=0x839080) at /root/posix_quic/src/socket_entry.cpp:457
    #2  0x00000000004ca980 in net::QuicCryptoClientHandshaker::DoReceiveSHLO(net::CryptoHandshakeMessage const*, net::QuicCryptoClientConfig::CachedState*) ()
    #3  0x00000000004cb208 in net::QuicCryptoClientHandshaker::DoHandshakeLoop(net::CryptoHandshakeMessage const*) ()
    #4  0x00000000004cb99c in net::QuicCryptoClientHandshaker::OnHandshakeMessage(net::CryptoHandshakeMessage const&) ()
    #5  0x000000000048af5c in net::CryptoFramer::Process(base::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, net::Perspective) ()
    #6  0x000000000048b74c in net::CryptoFramer::ProcessInput(base::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, net::Perspective) ()
    Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    (gdb) c

    posix_quic::Event::SetError

    (gdb) bt
    #0  posix_quic::Event::SetError (this=0x84cee0, err=9, quicErr=0) at /root/posix_quic/src/event.cpp:120
    #1  0x000000000044b704 in net::QuicSession::CloseStreamInner(unsigned int, bool) ()
    #2  0x0000000000465514 in net::QuartcStream::OnDataAvailable() ()
    #3  0x000000000045625c in net::QuicStreamSequencer::MaybeCloseStream() ()
    #4  0x0000000000456400 in net::QuicStreamSequencer::OnStreamFrame(net::QuicStreamFrame const&) ()
    #5  0x0000000000450bb8 in net::QuicStream::OnStreamFrame(net::QuicStreamFrame const&) ()
    #6  0x000000000044cb14 in net::QuicSession::OnStreamFrame(net::QuicStreamFrame const&) ()
    #7  0x000000000043210c in net::QuicConnection::OnStreamFrame(net::QuicStreamFrame const&) ()
    #8  0x000000000043fd64 in net::QuicFramer::ProcessFrameData(net::QuicDataReader*, net::QuicPacketHeader const&) [clone .part.162] [clone .constprop.172] ()
    #9  0x00000000004402f8 in net::QuicFramer::ProcessDataPacket(net::QuicDataReader*, net::QuicPacketHeader*, net::QuicEncryptedPacket const&, char*, unsigned long) [clone .part.163] [clone .constprop.166] ()
    #10 0x0000000000440724 in net::QuicFramer::ProcessPacket(net::QuicEncryptedPacket const&) ()
    #11 0x00000000004349f8 in net::QuicConnection::ProcessUdpPacket(net::QuicSocketAddress const&, net::QuicSocketAddress const&, net::QuicReceivedPacket const&) ()
    #12 0x00000000004172a0 in posix_quic::QuicSocketEntry::ProcessUdpPacket (this=this@entry=0x839080, self_address=..., peer_address=..., packet=...) at /root/posix_quic/src/socket_entry.cpp:415
    #13 0x0000000000407098 in posix_quic::QuicEpollerEntry::Wait (this=this@entry=0x835950, events=0x461830 <net::QuicSocketAddressImpl::QuicSocketAddressImpl(sockaddr_storage const&)+48>, events@entry=0xffffffff9128, maxevents=65535, 
        maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/epoller_entry.cpp:376
    #14 0x0000000000415874 in posix_quic::QuicEpollWait (epfd=3, epfd@entry=3160372, events=events@entry=0xffffffff9128, maxevents=maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/quic_socket.cpp:494
    #15 0x0000000000401e04 in doLoop (ep=3160372, ep@entry=3) at /root/posix_quic/test/client/src/client.cpp:37
    #16 0x00000000004009cc in main () at /root/posix_quic/test/client/src/client.cpp:149

     SetCloseByPeer

    void QuartcSession::OnConnectionClosed(QuicErrorCode error,
                                           const QuicString& error_details,
                                           ConnectionCloseSource source) {
      QuicSession::OnConnectionClosed(error, error_details, source);
      DCHECK(session_delegate_);
      session_delegate_->OnConnectionClosed(error, error_details, source);
    }
    Thread 1 "server" hit Breakpoint 1, 0x00000000004507c0 in net::QuicStream::OnConnectionClosed(net::QuicErrorCode, net::ConnectionCloseSource) ()
    (gdb) bt
    #0  0x00000000004507c0 in net::QuicStream::OnConnectionClosed(net::QuicErrorCode, net::ConnectionCloseSource) ()
    #1  0x000000000044a2cc in net::QuicSession::OnConnectionClosed(net::QuicErrorCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, net::ConnectionCloseSource) ()
    #2  0x0000000000464aa0 in net::QuartcSession::OnConnectionClosed(net::QuicErrorCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, net::ConnectionCloseSource) ()
    #3  0x000000000042d8f0 in net::QuicConnection::TearDownLocalConnectionState(net::QuicErrorCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, net::ConnectionCloseSource) ()
    Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    Thread 1 "server" hit Breakpoint 2, 0x000000000042d8a8 in net::QuicConnection::TearDownLocalConnectionState(net::QuicErrorCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, net::ConnectionCloseSource) ()
    (gdb) bt
    #0  0x000000000042d8a8 in net::QuicConnection::TearDownLocalConnectionState(net::QuicErrorCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, net::ConnectionCloseSource) ()
    #1  0x00000000004305b0 in net::QuicConnection::CloseConnection(net::QuicErrorCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, net::ConnectionCloseBehavior) [clone .localalias.197] ()
    #2  0x0000000000427140 in posix_quic::QuicConnectionVisitor::CheckForNoAckTimeout (this=0x191397d8) at /root/posix_quic/src/connection_visitor.cpp:46
    #3  posix_quic::NoAckAlarmDelegate::OnAlarm (this=<optimized out>) at /root/posix_quic/src/connection_visitor.cpp:12
    #4  0x00000000004621bc in net::(anonymous namespace)::QuartcAlarm::Run() ()
    #5  0x0000000000421aec in posix_quic::QuicTaskRunner::RunOnce (this=this@entry=0x19123ce0) at /root/posix_quic/src/task_runner.cpp:80
    #6  0x0000000000406550 in posix_quic::QuicEpollerEntry::Wait (this=this@entry=0x19123950, events=0x810000 <tunable_list+448>, events@entry=0xfffffab8c668, maxevents=0, maxevents@entry=1024, timeout=timeout@entry=6000)
        at /root/posix_quic/src/epoller_entry.cpp:272
    #7  0x000000000041577c in posix_quic::QuicEpollWait (epfd=3, epfd@entry=0, events=events@entry=0xfffffab8c668, maxevents=maxevents@entry=1024, timeout=timeout@entry=6000) at /root/posix_quic/src/quic_socket.cpp:494
    #8  0x0000000000401f74 in doLoop (ep=0, ep@entry=3, listenSock=0, listenSock@entry=1) at /root/posix_quic/test/server/src/server.cpp:48
    #9  0x00000000004009ac in main () at /root/posix_quic/test/server/src/server.cpp:153
    (gdb) quit
    Event::EventTrigger::Wait  没有调用
    void Event::EventTrigger::Wait(int timeout)
    {
        std::unique_lock<std::mutex> lock(cvMtx);
        if (triggered) {
            triggered = false;
            return ;
        }
        if (timeout > 0) {
            cv.wait_for(lock, std::chrono::milliseconds(timeout));
        } else if (timeout == 0) {
            return ;
        } else {
            cv.wait(lock);
        }
    }

    总结

     

         
    QuicEpollerEntry::QuicEpollerEntry()
    {
        SetFd(epoll_create(10240));
        trigger_.epollfd = Fd();
        trigger_.epollEntry = this;
    }
    QuicEpollerEntry::AddInner
        Event::EventWaiter waiter = { &qev->events, &qev->revents };
        if (!entry->StartWait(waiter, &trigger_)) {
            errno = EBADF;
            return -1;
        }
        fds_[fd] = std::make_pair(EntryWeakPtr(entry), qev);

       1、 QuicEpollerEntry::Wait会调poll遍历fds_[fd]: <entry,event>

     2、Event::TriggerWithoutLock会更改qev


    void Event::TriggerWithoutLock(short int event) { for (auto & kv : waitings_) { EventTrigger * trigger = kv.first; EventWaiter & waiter = kv.second; switch (event) { case POLLIN: __atomic_fetch_or(waiter.revents, POLLIN, std::memory_order_seq_cst); trigger->Trigger(POLLIN); }

    struct EventWaiter {
    short int* events;
    short int* revents;
    };


    EventWaiter初始化 

    EntryCategory::Socket EntryCategory::Stream都会调用QuicEpollCtl(ep, EPOLL_CTL_ADD

    int QuicEpollerEntry::AddInner(int fd, struct epoll_event * event)
    std::shared_ptr<quic_epoll_event> qev(new quic_epoll_event);
    qev->events = Epoll2Poll(event->events);
    qev->data = event->data;
    qev->revents = 0;
    
    Event::EventWaiter waiter = { &qev->events, &qev->revents };
    if (!entry->StartWait(waiter, &trigger_)) {
    errno = EBADF;
    return -1;
    }


    EventWaiter 事件触发

    void Event::TriggerWithoutLock(short int event)
    {
    for (auto & kv : waitings_) {
    EventTrigger * trigger = kv.first;
    EventWaiter & waiter = kv.second;
    switch (event) {
    case POLLIN:
    __atomic_fetch_or(waiter.revents, POLLIN, std::memory_order_seq_cst);
    trigger->Trigger(POLLIN);
    }

    EventWaiter poll轮询

    int QuicEpollerEntry::Poll(struct epoll_event *events, int maxevents)
    {
    std::unique_lock<std::mutex> lock(mtx_);
    int i = 0;
    for (auto & kv : fds_) {
    if (i >= maxevents) break;
    
    quic_epoll_event & qev = *(kv.second.second);
    short int event = qev.events | POLLERR;
    
    // DebugPrint(dbg_event, "fd = %d, qev.revents = %s, event = %s",
    // kv.first, PollEvent2Str(qev.revents), PollEvent2Str(event));
    
    short int revents = __atomic_fetch_and(&qev.revents, ~event, std::memory_order_seq_cst);
    revents &= event;
    
    DebugPrint(dbg_event, "after __atomic_fetch_and fd = %d, qev.revents = %s, revents = %s",
    kv.first, PollEvent2Str(qev.revents), PollEvent2Str(revents));
    
    if (revents == 0) continue;
    
    struct epoll_event & ev = events[i++];
    ev.data = qev.data;
    ev.events = Poll2Epoll(revents);
    }
    
    DebugPrint(dbg_epoll, "QuicEpollerEntry::Poll returns %d", i);
    return i;
    }

     QuicEpollWait(ep, evs, sizeof(evs)/sizeof(struct epoll_event), 6000); 返回的参数 不是epoll_wait返回的参数, 是Poll(struct epoll_event *events, int maxevents)返回的

  • 相关阅读:
    gradle
    1-NIO使用
    处理非正常终止的错误
    一个取消多生产者单消费者的日志线程池服务
    executes()源码
    死锁
    CyclicBarrier使用
    Semaphore
    Spring学习(4)IOC容器配置bean:定义与实例化
    在Maven上Web项目添加Spring框架
  • 原文地址:https://www.cnblogs.com/dream397/p/14649232.html
Copyright © 2020-2023  润新知