On Thu, Feb 15, 2024, Anish Moorthy wrote: > @@ -167,19 +187,30 @@ struct uffd_desc *uffd_setup_demand_paging(int uffd_mode, useconds_t delay, > void uffd_stop_demand_paging(struct uffd_desc *uffd) > { > char c = 0; > - int ret; > + int i, ret; > > - ret = write(uffd->pipefds[1], &c, 1); > - TEST_ASSERT(ret == 1, "Unable to write to pipefd"); > + for (i = 0; i < uffd->num_readers; ++i) { > + ret = write(uffd->pipefds[i], &c, 1); > + TEST_ASSERT( > + ret == 1, "Unable to write to pipefd %i for uffd_desc %p", i, uffd); More coding style oddities. And storing the return code in "ret" is unnecessary, and arguably makes it more difficult to debug failures by not capturing the failing command in the assert message. > + } > > - ret = pthread_join(uffd->thread, NULL); > - TEST_ASSERT(ret == 0, "Pthread_join failed."); > + for (i = 0; i < uffd->num_readers; ++i) { > + ret = pthread_join(uffd->readers[i], NULL); > + TEST_ASSERT( > + ret == 0, "Pthread_join failed on reader %i for uffd_desc %p", i, uffd); Preferred kernel style is "!ret", not "ret == 0". Putting it all together: int i; for (i = 0; i < uffd->num_readers; ++i) TEST_ASSERT(write(uffd->pipefds[i], &c, 1) == 1, "Unable to write to pipefd %i for uffd_desc %p", i, uffd); for (i = 0; i < uffd->num_readers; ++i) TEST_ASSERT(!pthread_join(uffd->readers[i], NULL), "Pthread_join failed on reader %i for uffd_desc %p", i, uffd);