Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RockStream::request 线程安全问题 #13

Closed
hankai17 opened this issue May 22, 2020 · 2 comments
Closed

RockStream::request 线程安全问题 #13

hankai17 opened this issue May 22, 2020 · 2 comments

Comments

@hankai17
Copy link

RockStream作为AsyncSocketStream的子类 实现了上层协议的收发以及解析
在request方法里

RockResult::ptr RockStream::request(RockRequest::ptr req, uint32_t timeout_ms) {                                    
        ...
        RockCtx::ptr ctx = std::make_shared<RockCtx>();                                                             
        ctx->request = req;                                                                                         
        ctx->sn = req->getSn();                                                                                     
        ctx->timeout = timeout_ms;                                                                                  
        ctx->scheduler = sylar::Scheduler::GetThis();                                                               
        ctx->fiber = sylar::Fiber::GetThis();
        addCtx(ctx); 
        uint64_t ts = sylar::GetCurrentMS();                                                                        
        ctx->timer = sylar::IOManager::GetThis()->addTimer(timeout_ms,                                              
                std::bind(&RockStream::onTimeOut, shared_from_this(), ctx));                                        
        enqueue(ctx);                                                                                               
        sylar::Fiber::YieldToHold();
        auto rt = std::make_shared<RockResult>(ctx->result, ctx->resultStr, sylar::GetCurrentMS() - ts, ctx->response, req);
        rt->server = getRemoteAddressString();                                                                      
        return rt;                           

在request方法里 在把ctx入队后 调YieldToHold等待响应
ctx入队后唤醒AsyncSocketStream的发送队列 将请求发出去 如果有响应则调doRsp

void AsyncSocketStream::Ctx::doRsp() {
    Scheduler* scd = scheduler;
    if(!sylar::Atomic::compareAndSwapBool(scheduler, scd, (Scheduler*)nullptr)) {
        return;
    }
    if(!scd || !fiber) {
        return;
    }
    if(timer) {
        timer->cancel();
        timer = nullptr;
    }

    if(timed) {
        result = TIMEOUT;
        resultStr = "timeout";
    }
    scd->schedule(&fiber);
}

doRsp里调schedule(&fiber) 返回到YeildToHold处

这里有个疑问就是 在多线程情况下
如果request里 入队后很快得到响应 快到还没来及调YeildToHold 那么就会出问题

@hankai17
Copy link
Author

咨询一下RockStream 应用场景是IOManager(1) 单线程这种情况下吗?
如果不是单线程 多线程下怎么确保RockStream发送 接收 线程安全

@hankai17
Copy link
Author

hankai17 commented May 23, 2020

if(it->fiber && it->fiber->getState() == Fiber::EXEC) {

是线程安全的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant