#ifdef OS_darwin_10 #include <dispatch/dispatch.h> #endif #include <gtest/gtest.h> #include <sys/types.h> #include <sys/mman.h> #import <Foundation/Foundation.h> #include "test_utils.h" #include "gtest_fixture_injection.h" #ifndef OS_darwin #error "This file should be built on Darwin only." #endif class Task { public: Task() {}; void Run() { printf("Inside Task::Run()\n"); } }; @interface TaskOperation : NSOperation { @private Task *task_; } + (id)taskOperationWithTask:(Task*)task; - (id)initWithTask:(Task*)task; @end // @interface TaskOperation @implementation TaskOperation + (id)taskOperationWithTask:(Task*)task { return [[TaskOperation alloc] initWithTask:task]; } - (id)init { return [self initWithTask:NULL]; } - (id)initWithTask:(Task*)task { if ((self = [super init])) { task_ = task; } return self; } - (void)main { if (!task_) { return; } task_->Run(); delete task_; task_ = NULL; } - (void)dealloc { if (task_) delete task_; [super dealloc]; } @end // @implementation TaskOperation namespace MacTests { // Regression test for https://bugs.kde.org/show_bug.cgi?id=216837. TEST(MacTests, WqthreadRegressionTest) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Task *task = new Task(); NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperation:[TaskOperation taskOperationWithTask:task]]; sleep(1); // wait for the worker thread to start. // If the bug is still there, ThreadSanitizer should crash after starting // the worker thread. [pool release]; } // Regression test for a bug with passing a 32-bit value instead of a 64-bit // as the last parameter to mmap(). TEST(MacTests, ShmMmapRegressionTest) { #ifdef OS_darwin_9 int md; void *virt_addr; shm_unlink("apple.shm.notification_center"); md = shm_open("apple.shm.notification_center", 0, 0); if (md != -1) { virt_addr = mmap(0, 4096, 1, 1, md, 0); if (virt_addr == (void*)-1) { shm_unlink("apple.shm.notification_center"); FAIL() << "mmap returned -1"; } else { munmap(virt_addr, 4096); shm_unlink("apple.shm.notification_center"); } } else { printf("shm_open() returned -1\n"); } #endif } } // namespace MacTests #ifdef OS_darwin_10 namespace SnowLeopardTests { int GLOB = 0; StealthNotification sn1, sn2; void worker_do_add(int *var, int val, StealthNotification *notify, StealthNotification *waitfor) { (*var) += val; fprintf(stderr, "var=%d\n", *var); notify->signal(); // Make sure that the callbacks are ran on different threads. if (waitfor) { waitfor->wait(); } } TEST(SnowLeopardTests, GCD_GlobalQueueRace) { ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "SnowLeopardTests.GCD_GlobalQueueRace TP."); dispatch_queue_t queue = dispatch_get_global_queue(0,0); dispatch_block_t block_plus = ^{ worker_do_add(&GLOB, 1, &sn1, &sn2); }; dispatch_block_t block_minus = ^{ worker_do_add(&GLOB, -1, &sn2, NULL); }; dispatch_async(queue, block_plus); dispatch_async(queue, block_minus); sn1.wait(); sn2.wait(); } } // namespace SnowLeopardTests #endif