recognizer const & literal::get_recognizer(std::map<std::string, state_machine> const &, std::map<std::u32string, builtins::string_terminal> & literals) const { auto i = literals.find(contents); if (i == literals.end()) { return literals.emplace(std::piecewise_construct, forward_as_tuple(contents), forward_as_tuple(contents)).first->second; } else { return i->second; } }
Listener* Invoker::subscribe(Exception& ex, Peer& peer,const string& name,Writer& writer,double start) { auto it(_publications.emplace(piecewise_construct,forward_as_tuple(name),forward_as_tuple(name)).first); Publication& publication(it->second); Listener* pListener = publication.addListener(ex, peer,writer,start==-3000 ? true : false); if (ex) { if(!publication.publisher() && publication.listeners.count()==0) _publications.erase(it); } return pListener; }
Publication* Invoker::publish(Exception& ex, Peer& peer,const string& name) { auto it(_publications.emplace(piecewise_construct,forward_as_tuple(name),forward_as_tuple(name)).first); Publication* pPublication = &it->second; pPublication->start(ex, peer); if (ex) { if (!pPublication->publisher() && pPublication->listeners.count() == 0) _publications.erase(it); return NULL; } return pPublication; }
index_visitor<F, Args &&...> make_index_visitor(Args &&... args) { return {forward_as_tuple(forward<Args>(args)...)}; }
void RTMFPFlow::receive(UInt64 _stage,UInt64 deltaNAck,PacketReader& fragment,UInt8 flags) { if(_completed) return; if(!_pStream) { // if this==FlowNull fail("RTMFPMessage received for a RTMFPFlow unknown"); (UInt64&)this->_stage = _stage; return; } // TRACE("RTMFPFlow ",id," _stage ",_stage); UInt64 nextStage = this->_stage+1; if(_stage < nextStage) { DEBUG("Stage ",_stage," on flow ",id," has already been received"); return; } if(deltaNAck>_stage) { WARN("DeltaNAck ",deltaNAck," superior to _stage ",_stage," on flow ",id); deltaNAck=_stage; } if(this->_stage < (_stage-deltaNAck)) { auto it=_fragments.begin(); while(it!=_fragments.end()) { if( it->first > _stage) break; // leave all stages <= _stage PacketReader packet(it->second->data(),it->second->size()); onFragment(it->first,packet,it->second.flags); if(it->second.flags&MESSAGE_END) { complete(); return; // to prevent a crash bug!! (double fragments deletion) } _fragments.erase(it++); } nextStage = _stage; } if(_stage>nextStage) { // not following _stage, bufferizes the _stage auto it = _fragments.lower_bound(_stage); if(it==_fragments.end() || it->first!=_stage) { _fragments.emplace_hint(it,piecewise_construct,forward_as_tuple(_stage),forward_as_tuple(_poolBuffers,fragment,flags)); if(_fragments.size()>100) DEBUG("_fragments.size()=",_fragments.size()); } else DEBUG("Stage ",_stage," on flow ",id," has already been received"); } else { onFragment(nextStage++,fragment,flags); if(flags&MESSAGE_END) complete(); auto it=_fragments.begin(); while(it!=_fragments.end()) { if( it->first > nextStage) break; PacketReader packet(it->second->data(), it->second->size()); onFragment(nextStage++,packet,it->second.flags); if(it->second.flags&MESSAGE_END) { complete(); return; // to prevent a crash bug!! (double fragments deletion) } _fragments.erase(it++); } } }
void Daemon::on_tcp_connect(uvpp::error error) { auto tcp_conn_ptr = make_unique<TCPConnection>(m_server_info, m_shares, m_loop); TCPConnection& tcp_conn = *tcp_conn_ptr; m_tcp_listen_conn.accept(tcp_conn.m_tcp_conn); protocol::ProtocolState& pstate = tcp_conn.m_cs_protocol; string peer_ip; int port; bool ip4; const bool getpeername_ok = tcp_conn.m_tcp_conn.getpeername(ip4, peer_ip, port); assert(getpeername_ok); (void)getpeername_ok; ostringstream os; os << "tcp://" << peer_ip << ":" << port; string peer_ = os.str(); //string peer_ = fs("tcp://" << peer_ip << ":" << port); // will go out of scope auto res = m_connections.emplace(piecewise_construct, forward_as_tuple(move(peer_)), forward_as_tuple(move(tcp_conn_ptr))); assert(res.second); const string& peer = res.first->first; // reference that will stay valid // we need to be very careful about capturing objects that might go out of scope. The Connection // is owned by Server::m_connections, so remains valid. // tcp_conn and p_state are owned by the Server. (m_connections) auto close_cb = [this, peer]() { m_connections.erase(peer); }; // write finished callback auto write_cb = [&](uvpp::error) { if (! error) pstate.on_write_finished(); else { cerr << "TCP client write error: " << peer << endl; tcp_conn.m_tcp_conn.close(close_cb); } }; // function to be called when the the protocol needs to write auto do_write = [&](const char* buff, size_t sz) { tcp_conn.m_tcp_conn.write(buff, sz, write_cb); }; auto read_cb = [&](const char* buff, ssize_t len) { if (len < 0) { cerr << "TCP client read error: " << peer << endl; tcp_conn.m_tcp_conn.close(close_cb); } else pstate.input(buff, static_cast<size_t>(len)); }; // set function to call when the protocol has data to write pstate.set_write_fun(do_write); tcp_conn.m_tcp_conn.read_start(read_cb); }