void OutConnValidator::OnInput() { m_ts.Update(); assert(m_buf.Size() < 68); t_byte buf[68]; size_t read_n = 68 - m_buf.Size(); assert(read_n <= 68); int rn = m_stream_sock.Recv(buf, read_n); assert(rn <= 68); if(rn > 0) { m_buf.Insert(buf, rn); assert(m_buf.Size() <= 68); if(m_buf.Size() == 68) { check_connection_handshake(); GetSelector()->RemoveHandler(this); } }else if(rn == -1 && NetGetLastError() == EWOULDBLOCK) { //等待下次 }else { DEBUG_PRINT0("OutConnValidator::OnInput connection abort\n"); //网络连接断开 MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry)); GetSelector()->RemoveHandler(this); } }
void PeerConnector::on_connected(NetSpace::NetHandle hdl) { assert(GetSelector() != 0); OutConnValidator *pov = new OutConnValidator(hdl, m_peer_entry, m_task_id, m_infohash, m_peer_id); assert(pov != 0); bool res = GetSelector()->RegisterHandler(pov); assert(res); pov->Release(); }
void OutConnValidator::OnOutput() { m_ts.Update(); assert(m_buf.Size() > 0); int wn = m_stream_sock.Send(m_buf.Data(),m_buf.Size()); if(wn > 0) { m_buf.Erase(wn); if(m_buf.Size() == 0) { Mask(NetSpace::INPUT_MASK|NetSpace::TIMER_MASK); } }else if(wn == -1 && NetGetLastError() == EWOULDBLOCK) { //等待下一次可写 }else { //失败 DEBUG_PRINT0("OutConnValidator::OnOutput() failed\n"); MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry)); GetSelector()->RemoveHandler(this); } }
void OutConnValidator::OnTimer() { if(m_ts.ElapsedMillisecond() >= VALIDATOR_TIMEOUT) { MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry)); GetSelector()->RemoveHandler(this); } }
void InConnValidator::OnTimer() { if(m_ts.ElapsedMillisecond() >= VALIDATOR_TIMEOUT) { //MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry)); DEBUG_PRINT0("accepted peer connection timeout\n"); GetSelector()->RemoveHandler(this); } }
void InConnValidator::OnInput() { m_ts.Update(); t_byte buf[68]; int read_len = 68 - m_buf.Size(); assert(read_len <= 68); int rn = m_stream_sock.Recv(buf, read_len); if(rn > 0) { m_buf.Insert(buf, rn); assert(m_buf.Size() <= 68); if(m_buf.Size() == 68) { if(!check_connection_handshake()) { //DEBUG_PRINT0("check_connection_handshake failed\n"); GetSelector()->RemoveHandler(this); return; }else { assert(m_buf.Size() == 68); Mask(NetSpace::OUTPUT_MASK|NetSpace::TIMER_MASK); } } }else if(rn == -1 && NetGetLastError() == EWOULDBLOCK) { //等待下次; }else { DEBUG_PRINT0("accepted peer connection abort\n"); GetSelector()->RemoveHandler(this); } }
void InConnValidator::OnOutput() { m_ts.Update(); int wn = m_stream_sock.Send(m_buf.Data(), m_buf.Size()); if(wn > 0) { m_buf.Erase(wn); if(m_buf.IsEmpty()) { MsgSpace::PostMessageEx(m_task_id, new NetConnEstablished(m_stream_sock.Duplicate(), REMOTE, m_peer_id, m_infohash, m_peer_entry, m_ext_info)); GetSelector()->RemoveHandler(this); } }else if(wn == -1 && NetGetLastError() == EWOULDBLOCK) { //等待下次; }else { DEBUG_PRINT0("accepted peer connection abort\n"); GetSelector()->RemoveHandler(this); } }
CodeGen::RValue CGObjCJit::EmitMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType, Selector Sel, llvm::Value *Arg0, llvm::Value *Arg0Class, const CallArgList &CallArgs, const ObjCMethodDecl *Method) { llvm::Value *Arg1 = GetSelector(CGF, Sel); CallArgList ActualArgs; ActualArgs.add(RValue::get(Arg0), CGF.getContext().getObjCIdType()); ActualArgs.add(RValue::get(Arg1), CGF.getContext().getObjCSelType()); ActualArgs.addFrom(CallArgs); if (Method) assert(CGM.getContext().getCanonicalType(Method->getResultType()) == CGM.getContext().getCanonicalType(ResultType) && "Result type mismatch!"); // Perform the following: // imp = class_getMethodImplementation( Arg0Class, Arg1 ); // (*imp)( Arg0, Arg1, CallArgs ); llvm::CallInst *getImp; // Unfortunately, using the GNU runtime version of // class_getMethodImplementation and then calling the resulting // IMP doesn't work unless objc_msg_lookup was already // called first. TODO: avoid doing this every time // if (fn_objc_msg_lookup.isValid()) { getImp = CGF.Builder.CreateCall2(fn_objc_msg_lookup, Arg0, Arg1); } else { // use the universal way getImp = CGF.Builder.CreateCall2(fn_class_getMethodImplementation, Arg0Class, Arg1); } MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs); llvm::Value *theImp = CGF.Builder.CreateBitCast(getImp, MSI.MessengerType); return CGF.EmitCall(MSI.CallInfo, theImp, Return, ActualArgs); }
void CGObjCJit::AddMethodsToClass(void *theClass) { // Methods need to be added at runtime. Method function pointers (IMP) // are not available until then. CGBuilderTy Builder(JitInitBlock); CodeGen::CodeGenFunction CGF(CGM); void *theMetaclass = _object_getClass(theClass); llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator I = MethodDefinitions.begin(); while (I != MethodDefinitions.end()) { const ObjCMethodDecl *D = I->first; std::string TypeStr; CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D), TypeStr); const char* TypeCStr = // keep in a set MethodTypeStrings.insert(MethodTypeStrings.begin(), TypeStr)->c_str(); void *ClassObject = D->isClassMethod() ? theMetaclass : theClass; llvm::Value *ClassArg = llvm::Constant::getIntegerValue(ObjCTypes.ClassPtrTy, llvm::APInt(sizeof(void*) * 8, (uint64_t)ClassObject)); llvm::Value *SelectorArg = GetSelector(CGF, D->getSelector()); llvm::Value *TypeArg = llvm::Constant::getIntegerValue(ObjCTypes.Int8PtrTy, llvm::APInt(sizeof(void*) * 8, (uint64_t)TypeCStr)); llvm::Value *MethodArg = Builder.CreateBitCast(I->second, ImpPtrTy); Builder.CreateCall4(fn_class_addMethod, ClassArg, SelectorArg, MethodArg, TypeArg); I++; } // Done with list for this implementation, so clear it MethodDefinitions.clear(); }
llvm::Value *CGObjCJit::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl *Method) { return GetSelector(CGF, Method->getSelector()); }