MCPcopy Create free account
hub / github.com/apache/brpc / IsWriteComplete

Method IsWriteComplete

src/brpc/socket.cpp:1166–1219  ·  view source on GitHub ↗

Check if there're new requests appended. If yes, point old_head to reversed new requests and return false; If no: old_head is fully written, set _write_head to NULL and return true; old_head is not written yet, keep _write_head unchanged and return false; `old_head' is last new_head got from this function or (in another word) tail of current writing list. `singular_node' is true iff `old_head' is

Source from the content-addressed store, hash-verified

1164// tail of current writing list.
1165// `singular_node' is true iff `old_head' is the only node in its list.
1166bool Socket::IsWriteComplete(Socket::WriteRequest* old_head,
1167 bool singular_node,
1168 Socket::WriteRequest** new_tail) {
1169 CHECK(NULL == old_head->next);
1170 // Try to set _write_head to NULL to mark that the write is done.
1171 WriteRequest* new_head = old_head;
1172 WriteRequest* desired = NULL;
1173 bool return_when_no_more = true;
1174 if (!old_head->data.empty() || !singular_node) {
1175 desired = old_head;
1176 // Write is obviously not complete if old_head is not fully written.
1177 return_when_no_more = false;
1178 }
1179 if (_write_head.compare_exchange_strong(
1180 new_head, desired, butil::memory_order_acquire)) {
1181 // No one added new requests.
1182 if (new_tail) {
1183 *new_tail = old_head;
1184 }
1185 return return_when_no_more;
1186 }
1187 CHECK_NE(new_head, old_head);
1188 // Above acquire fence pairs release fence of exchange in Write() to make
1189 // sure that we see all fields of requests set.
1190
1191 // Someone added new requests.
1192 // Reverse the list until old_head.
1193 WriteRequest* tail = NULL;
1194 WriteRequest* p = new_head;
1195 do {
1196 while (p->next == WriteRequest::UNCONNECTED) {
1197 // TODO(gejun): elaborate this
1198 sched_yield();
1199 }
1200 WriteRequest* const saved_next = p->next;
1201 p->next = tail;
1202 tail = p;
1203 p = saved_next;
1204 CHECK(p != NULL);
1205 } while (p != old_head);
1206
1207 // Link old list with new list.
1208 old_head->next = tail;
1209 // Call Setup() from oldest to newest, notice that the calling sequence
1210 // matters for protocols using pipelined_count, this is why we don't
1211 // call Setup in above loop which is from newest to oldest.
1212 for (WriteRequest* q = tail; q; q = q->next) {
1213 q->Setup(this);
1214 }
1215 if (new_tail) {
1216 *new_tail = new_head;
1217 }
1218 return false;
1219}
1220
1221int Socket::WaitEpollOut(int fd, bool pollin, const timespec* abstime) {
1222 if (!ValidFileDescriptor(fd)) {

Callers 1

KeepWriteMethod · 0.80

Calls 3

emptyMethod · 0.45
SetupMethod · 0.45

Tested by

no test coverage detected