|
@@ -241,7 +241,7 @@ ssize_t faux_async_write(faux_async_t *async, void *data, size_t len)
|
|
|
|
|
|
// Copy data
|
|
|
chunk_ptr = faux_list_data(faux_list_tail(async->o_list));
|
|
|
- copy_len = (len < (size_t)bytes_free) ? len : (size_t)bytes_free;
|
|
|
+ copy_len = (data_left < (size_t)bytes_free) ? data_left : (size_t)bytes_free;
|
|
|
memcpy(chunk_ptr + async->o_wpos, data + len - data_left,
|
|
|
copy_len);
|
|
|
async->o_wpos += copy_len;
|
|
@@ -278,6 +278,8 @@ static ssize_t data_avail(faux_list_t *list, size_t rpos, size_t wpos)
|
|
|
|
|
|
ssize_t faux_async_out(faux_async_t *async)
|
|
|
{
|
|
|
+ ssize_t total_written = 0;
|
|
|
+
|
|
|
assert(async);
|
|
|
if (!async)
|
|
|
return -1;
|
|
@@ -287,29 +289,55 @@ ssize_t faux_async_out(faux_async_t *async)
|
|
|
char *chunk_ptr = NULL;
|
|
|
ssize_t data_to_write = 0;
|
|
|
ssize_t bytes_written = 0;
|
|
|
+ bool_t postpone = BOOL_FALSE;
|
|
|
|
|
|
node = faux_list_head(async->o_list);
|
|
|
+ if (!node) // List is empty while o_size > 0
|
|
|
+ return -1;
|
|
|
chunk_ptr = faux_list_data(faux_list_head(async->o_list));
|
|
|
data_to_write = data_avail(async->o_list,
|
|
|
async->o_rpos, async->o_wpos);
|
|
|
- if (data_to_write < 0)
|
|
|
+ if (data_to_write <= 0) // Strange case
|
|
|
return -1;
|
|
|
+
|
|
|
bytes_written = write(async->fd, chunk_ptr + async->o_rpos,
|
|
|
data_to_write);
|
|
|
- if (bytes_written <= 0)
|
|
|
- return bytes_written;
|
|
|
- async->o_size -= bytes_written;
|
|
|
- if (bytes_written != data_to_write) {
|
|
|
+ if (bytes_written > 0) {
|
|
|
+ async->o_size -= bytes_written;
|
|
|
+ total_written += bytes_written;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (bytes_written < 0) {
|
|
|
+ if ( // Something went wrong
|
|
|
+ (errno != EINTR) &&
|
|
|
+ (errno != EAGAIN) &&
|
|
|
+ (errno != EWOULDBLOCK)
|
|
|
+ )
|
|
|
+ return -1;
|
|
|
+ // Postpone next read
|
|
|
+ postpone = BOOL_TRUE;
|
|
|
+
|
|
|
+ // Not whole data block was written
|
|
|
+ } else if (bytes_written != data_to_write) {
|
|
|
async->o_rpos += bytes_written;
|
|
|
+ // Postpone next read
|
|
|
+ postpone = BOOL_TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Postponed
|
|
|
+ if (postpone) {
|
|
|
// Execute callback
|
|
|
if (async->stall_cb)
|
|
|
async->stall_cb(async, async->o_size,
|
|
|
async->stall_udata);
|
|
|
- return async->o_size;
|
|
|
+ break;
|
|
|
}
|
|
|
+
|
|
|
+ // Not postponed. Current chunk was fully written. So
|
|
|
+ // remove it from list.
|
|
|
async->o_rpos = 0;
|
|
|
faux_list_del(async->o_list, node);
|
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
+ return total_written;
|
|
|
}
|