示例#1
0
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);
		}
}
示例#2
0
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();
}
示例#3
0
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);
		}

}
示例#4
0
void OutConnValidator::OnTimer()
{
		if(m_ts.ElapsedMillisecond() >= VALIDATOR_TIMEOUT)
		{
				MsgSpace::PostMessageEx(m_task_id, new NetConnectPeerFailed(m_peer_entry));
				GetSelector()->RemoveHandler(this);
		}
}
示例#5
0
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);
		}


}
示例#6
0
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);
		}
}
示例#7
0
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());
}