src: error or NULL links they happen on close

Right after `uv_link_close()` all links will be unchained, meaning that
they `link->parent` is NULL. Instead of crashing on calls like:

`uv_link_try_write(link->parent, ...)`

Make them return `UV_EFAULT`, indicating that no parent is present
anymore. Alternatively, these checks could be done in user code, but it
will make it too cumbersome.
This commit is contained in:
Fedor Indutny 2016-06-03 14:52:38 -04:00
parent 88ffbdbeba
commit 201448c9bb
2 changed files with 16 additions and 0 deletions

View File

@ -50,6 +50,8 @@ int uv_link_propagate_write(uv_link_t* link, uv_link_t* source,
const uv_buf_t bufs[], unsigned int nbufs,
uv_stream_t* send_handle,
uv_link_write_cb cb, void* arg) {
if (link == NULL)
return UV_EFAULT;
CLOSE_WRAP(link->methods->write(link, source, bufs, nbufs, send_handle, cb,
arg));
}
@ -59,16 +61,22 @@ int uv_link_propagate_shutdown(uv_link_t* link,
uv_link_t* source,
uv_link_shutdown_cb cb,
void* arg) {
if (link == NULL)
return UV_EFAULT;
CLOSE_WRAP(link->methods->shutdown(link, source, cb, arg));
}
int uv_link_read_start(uv_link_t* link) {
if (link == NULL)
return UV_EFAULT;
CLOSE_WRAP(link->methods->read_start(link));
}
int uv_link_read_stop(uv_link_t* link) {
if (link == NULL)
return UV_EFAULT;
CLOSE_WRAP(link->methods->read_stop(link));
}
@ -76,6 +84,8 @@ int uv_link_read_stop(uv_link_t* link) {
int uv_link_try_write(uv_link_t* link,
const uv_buf_t bufs[],
unsigned int nbufs) {
if (link == NULL)
return UV_EFAULT;
CLOSE_WRAP(link->methods->try_write(link, bufs, nbufs));
}

View File

@ -19,10 +19,16 @@ static void c_close_cb(uv_link_t* l) {
static void b_read_cb(uv_link_observer_t* o, ssize_t nread, const uv_buf_t* d) {
b_reads |= 1 << nread;
if (nread == 2) {
uv_buf_t tmp;
CHECK_EQ(a.close_depth, 0, "depth check");
CHECK_EQ(b.close_depth, 2, "depth check");
CHECK_EQ(c.close_depth, 1, "depth check");
uv_link_close((uv_link_t*) &c, c_close_cb);
CHECK_EQ(o->parent, NULL, "parent should be zeroed");
CHECK_EQ(uv_link_try_write(o->parent, &tmp, 0), UV_EFAULT,
"write should fail");
} else {
CHECK_EQ(a.close_depth, 0, "depth check");
CHECK_EQ(b.close_depth, 1, "depth check");