]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Darwin: remove global variable used in aio_return
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 18 Nov 2023 06:34:00 +0000 (07:34 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 18 Nov 2023 06:34:00 +0000 (07:34 +0100)
This was using a global variable to signify a read success
between pre- and post- aio_return. I don't think that this
was safe. There could be multiple calls to aio_return on
different threads. The global aiocpb_table is safe enough
as the pointers to control block are unique. However if two
threads manipulate was_a_successful_aio_read there's no way
of telling them apart. Rather than trying to make
was_a_successful_aio_read thread safe I did the same as on
FreeBSD and removed post- aio_return and now do everything
in pre- aio_return. No global variable, no thread hazard.

coregrind/m_syswrap/syswrap-darwin.c

index 3b8ceda3e25270b544b1805f6743be8dede1d28d..01281caf4bc017529a8b06062a28367c1866a636 100644 (file)
@@ -4580,8 +4580,6 @@ static void aio_init(void)
    aio_init_done = True;
 }
 
-static Bool was_a_successful_aio_read = False;
-
 PRE(aio_return)
 {
    struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1;
@@ -4589,22 +4587,21 @@ PRE(aio_return)
    // contents of the struct.
    PRINT( "aio_return ( %#lx )", ARG1 );
    PRE_REG_READ1(long, "aio_return", struct vki_aiocb*, aiocbp);
-
-   if (!aio_init_done) aio_init();
-   was_a_successful_aio_read = VG_(OSetWord_Remove)(aiocbp_table, (UWord)aiocbp);
-}
-POST(aio_return)
-{
-   // If we found the aiocbp in our own table it must have been an aio_read(),
-   // so mark the buffer as written.  If we didn't find it, it must have been
-   // an aio_write() or a bogus aio_return() (eg. a second one on the same
-   // aiocbp).  Either way, the buffer won't have been written so we don't
-   // have to mark the buffer as written.
-   if (was_a_successful_aio_read) {
-      struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1;
-      POST_MEM_WRITE((Addr)aiocbp->aio_buf, aiocbp->aio_nbytes);
-      was_a_successful_aio_read = False;
+   if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) {
+      SET_STATUS_from_SysRes(VG_(do_syscall1)(SYSNO, ARG1));
+      if (SUCCESS && RES >= 0) {
+         struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1;
+         if (!aio_init_done) {
+            aio_init();
+         }
+         if (VG_(OSetWord_Remove)(aiocbp_table, (UWord)aiocbp)) {
+            POST_MEM_WRITE((Addr)aiocbp->aio_buf, aiocbp->aio_nbytes);
+         }
+      }
+   } else {
+      SET_STATUS_Failure(VKI_EINVAL);
    }
+
 }
 
 PRE(aio_suspend)
@@ -10460,7 +10457,7 @@ const SyscallTableEntry ML_(syscall_table)[] = {
    _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(308)),   // old __pthread_cond_timedwait
 #endif
 // _____(__NR_aio_fsync), 
-   MACXY(__NR_aio_return,     aio_return), 
+   MACX_(__NR_aio_return,     aio_return),
    MACX_(__NR_aio_suspend,    aio_suspend), 
 // _____(__NR_aio_cancel), 
    MACX_(__NR_aio_error,      aio_error),