aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/neh/asio/tcp_socket_impl.cpp
blob: 98cef97561dc4dde5355e4f63b8b2de438a47d2c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "tcp_socket_impl.h"

using namespace NAsio;

TSocketOperation::TSocketOperation(TTcpSocket::TImpl& s, TPollType pt, TInstant deadline)
    : TFdOperation(s.Fd(), pt, deadline)
    , S_(s)
{
}

bool TOperationWrite::Execute(int errorCode) {
    if (errorCode) {
        H_(errorCode, Written_, *this);

        return true; //op. completed
    }

    TErrorCode ec;
    TContIOVector& iov = *Buffs_->GetIOvec();

    size_t n = S_.WriteSome(iov, ec);

    if (ec && ec.Value() != EAGAIN && ec.Value() != EWOULDBLOCK) {
        H_(ec, Written_ + n, *this);

        return true;
    }

    if (n) {
        Written_ += n;
        iov.Proceed(n);
        if (!iov.Bytes()) {
            H_(ec, Written_, *this);

            return true; //op. completed
        }
    }

    return false; //operation not compleled
}

bool TOperationWriteVector::Execute(int errorCode) {
    if (errorCode) {
        H_(errorCode, Written_, *this);

        return true; //op. completed
    }

    TErrorCode ec;

    size_t n = S_.WriteSome(V_, ec);

    if (ec && ec.Value() != EAGAIN && ec.Value() != EWOULDBLOCK) {
        H_(ec, Written_ + n, *this);

        return true;
    }

    if (n) {
        Written_ += n;
        V_.Proceed(n);
        if (!V_.Bytes()) {
            H_(ec, Written_, *this);

            return true; //op. completed
        }
    }

    return false; //operation not compleled
}

bool TOperationReadSome::Execute(int errorCode) {
    if (errorCode) {
        H_(errorCode, 0, *this);

        return true; //op. completed
    }

    TErrorCode ec;

    H_(ec, S_.ReadSome(Buff_, Size_, ec), *this);

    return true;
}

bool TOperationRead::Execute(int errorCode) {
    if (errorCode) {
        H_(errorCode, Read_, *this);

        return true; //op. completed
    }

    TErrorCode ec;
    size_t n = S_.ReadSome(Buff_, Size_, ec);
    Read_ += n;

    if (ec && ec.Value() != EAGAIN && ec.Value() != EWOULDBLOCK) {
        H_(ec, Read_, *this);

        return true; //op. completed
    }

    if (n) {
        Size_ -= n;
        if (!Size_) {
            H_(ec, Read_, *this);

            return true;
        }
        Buff_ += n;
    } else if (!ec) {  // EOF while read not all
        H_(ec, Read_, *this);
        return true;
    }

    return false;
}