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
| 1164 | // tail of current writing list. |
| 1165 | // `singular_node' is true iff `old_head' is the only node in its list. |
| 1166 | bool 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 | |
| 1221 | int Socket::WaitEpollOut(int fd, bool pollin, const timespec* abstime) { |
| 1222 | if (!ValidFileDescriptor(fd)) { |
no test coverage detected