@@ -665,230 +665,6 @@ int main(int argc, char **argv)
665
665
return 0;
666
666
}" HAVE_PR_SET_PTRACER )
667
667
668
- set (CMAKE_REQUIRED_LIBRARIES pthread )
669
- check_cxx_source_compiles ("
670
- #include <errno.h>
671
- #include <pthread.h>
672
- #include <time.h>
673
-
674
- int main()
675
- {
676
- pthread_mutexattr_t mutexAttributes;
677
- pthread_mutexattr_init(&mutexAttributes);
678
- pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED);
679
- pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE);
680
- pthread_mutexattr_setrobust(&mutexAttributes, PTHREAD_MUTEX_ROBUST);
681
-
682
- pthread_mutex_t mutex;
683
- pthread_mutex_init(&mutex, &mutexAttributes);
684
-
685
- pthread_mutexattr_destroy(&mutexAttributes);
686
-
687
- struct timespec timeoutTime;
688
- timeoutTime.tv_sec = 1; // not the right way to specify absolute time, but just checking availability of timed lock
689
- timeoutTime.tv_nsec = 0;
690
- pthread_mutex_timedlock(&mutex, &timeoutTime);
691
- pthread_mutex_consistent(&mutex);
692
-
693
- pthread_mutex_destroy(&mutex);
694
-
695
- int error = EOWNERDEAD;
696
- error = ENOTRECOVERABLE;
697
- error = ETIMEDOUT;
698
- error = 0;
699
- return error;
700
- }" HAVE_FULLY_FEATURED_PTHREAD_MUTEXES )
701
- set (CMAKE_REQUIRED_LIBRARIES )
702
-
703
- if (NOT CLR_CMAKE_HOST_ARCH_ARM AND NOT CLR_CMAKE_HOST_ARCH_ARM64 )
704
- set (CMAKE_REQUIRED_LIBRARIES pthread )
705
- check_cxx_source_runs ("
706
- // This test case verifies the pthread process-shared robust mutex's cross-process abandon detection. The parent process starts
707
- // a child process that locks the mutex, the process process then waits to acquire the lock, and the child process abandons the
708
- // mutex by exiting the process while holding the lock. The parent process should then be released from its wait, be assigned
709
- // ownership of the lock, and be notified that the mutex was abandoned.
710
-
711
- #include <sys/mman.h>
712
- #include <sys/time.h>
713
-
714
- #include <errno.h>
715
- #include <pthread.h>
716
- #include <stdio.h>
717
- #include <unistd.h>
718
-
719
- #include <new>
720
- using namespace std;
721
-
722
- struct Shm
723
- {
724
- pthread_mutex_t syncMutex;
725
- pthread_cond_t syncCondition;
726
- pthread_mutex_t robustMutex;
727
- int conditionValue;
728
-
729
- Shm() : conditionValue(0)
730
- {
731
- }
732
- } *shm;
733
-
734
- int GetFailTimeoutTime(struct timespec *timeoutTimeRef)
735
- {
736
- int getTimeResult = clock_gettime(CLOCK_REALTIME, timeoutTimeRef);
737
- if (getTimeResult != 0)
738
- {
739
- struct timeval tv;
740
- getTimeResult = gettimeofday(&tv, NULL);
741
- if (getTimeResult != 0)
742
- return 1;
743
- timeoutTimeRef->tv_sec = tv.tv_sec;
744
- timeoutTimeRef->tv_nsec = tv.tv_usec * 1000;
745
- }
746
- timeoutTimeRef->tv_sec += 30;
747
- return 0;
748
- }
749
-
750
- int WaitForConditionValue(int desiredConditionValue)
751
- {
752
- struct timespec timeoutTime;
753
- if (GetFailTimeoutTime(&timeoutTime) != 0)
754
- return 1;
755
- if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
756
- return 1;
757
-
758
- if (shm->conditionValue != desiredConditionValue)
759
- {
760
- if (GetFailTimeoutTime(&timeoutTime) != 0)
761
- return 1;
762
- if (pthread_cond_timedwait(&shm->syncCondition, &shm->syncMutex, &timeoutTime) != 0)
763
- return 1;
764
- if (shm->conditionValue != desiredConditionValue)
765
- return 1;
766
- }
767
-
768
- if (pthread_mutex_unlock(&shm->syncMutex) != 0)
769
- return 1;
770
- return 0;
771
- }
772
-
773
- int SetConditionValue(int newConditionValue)
774
- {
775
- struct timespec timeoutTime;
776
- if (GetFailTimeoutTime(&timeoutTime) != 0)
777
- return 1;
778
- if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
779
- return 1;
780
-
781
- shm->conditionValue = newConditionValue;
782
- if (pthread_cond_signal(&shm->syncCondition) != 0)
783
- return 1;
784
-
785
- if (pthread_mutex_unlock(&shm->syncMutex) != 0)
786
- return 1;
787
- return 0;
788
- }
789
-
790
- void DoTest_Child();
791
-
792
- int DoTest()
793
- {
794
- // Map some shared memory
795
- void *shmBuffer = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
796
- if (shmBuffer == MAP_FAILED)
797
- return 1;
798
- shm = new(shmBuffer) Shm;
799
-
800
- // Create sync mutex
801
- pthread_mutexattr_t syncMutexAttributes;
802
- if (pthread_mutexattr_init(&syncMutexAttributes) != 0)
803
- return 1;
804
- if (pthread_mutexattr_setpshared(&syncMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
805
- return 1;
806
- if (pthread_mutex_init(&shm->syncMutex, &syncMutexAttributes) != 0)
807
- return 1;
808
- if (pthread_mutexattr_destroy(&syncMutexAttributes) != 0)
809
- return 1;
810
-
811
- // Create sync condition
812
- pthread_condattr_t syncConditionAttributes;
813
- if (pthread_condattr_init(&syncConditionAttributes) != 0)
814
- return 1;
815
- if (pthread_condattr_setpshared(&syncConditionAttributes, PTHREAD_PROCESS_SHARED) != 0)
816
- return 1;
817
- if (pthread_cond_init(&shm->syncCondition, &syncConditionAttributes) != 0)
818
- return 1;
819
- if (pthread_condattr_destroy(&syncConditionAttributes) != 0)
820
- return 1;
821
-
822
- // Create the robust mutex that will be tested
823
- pthread_mutexattr_t robustMutexAttributes;
824
- if (pthread_mutexattr_init(&robustMutexAttributes) != 0)
825
- return 1;
826
- if (pthread_mutexattr_setpshared(&robustMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
827
- return 1;
828
- if (pthread_mutexattr_setrobust(&robustMutexAttributes, PTHREAD_MUTEX_ROBUST) != 0)
829
- return 1;
830
- if (pthread_mutex_init(&shm->robustMutex, &robustMutexAttributes) != 0)
831
- return 1;
832
- if (pthread_mutexattr_destroy(&robustMutexAttributes) != 0)
833
- return 1;
834
-
835
- // Start child test process
836
- int error = fork();
837
- if (error == -1)
838
- return 1;
839
- if (error == 0)
840
- {
841
- DoTest_Child();
842
- return -1;
843
- }
844
-
845
- // Wait for child to take a lock
846
- WaitForConditionValue(1);
847
-
848
- // Wait to try to take a lock. Meanwhile, child abandons the robust mutex.
849
- struct timespec timeoutTime;
850
- if (GetFailTimeoutTime(&timeoutTime) != 0)
851
- return 1;
852
- error = pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime);
853
- if (error != EOWNERDEAD) // expect to be notified that the robust mutex was abandoned
854
- return 1;
855
- if (pthread_mutex_consistent(&shm->robustMutex) != 0)
856
- return 1;
857
-
858
- if (pthread_mutex_unlock(&shm->robustMutex) != 0)
859
- return 1;
860
- if (pthread_mutex_destroy(&shm->robustMutex) != 0)
861
- return 1;
862
- return 0;
863
- }
864
-
865
- void DoTest_Child()
866
- {
867
- // Lock the robust mutex
868
- struct timespec timeoutTime;
869
- if (GetFailTimeoutTime(&timeoutTime) != 0)
870
- return;
871
- if (pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime) != 0)
872
- return;
873
-
874
- // Notify parent that robust mutex is locked
875
- if (SetConditionValue(1) != 0)
876
- return;
877
-
878
- // Wait a short period to let the parent block on waiting for a lock
879
- sleep(1);
880
-
881
- // Abandon the mutex by exiting the process while holding the lock. Parent's wait should be released by EOWNERDEAD.
882
- }
883
-
884
- int main()
885
- {
886
- int result = DoTest();
887
- return result >= 0 ? result : 0;
888
- }" HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES )
889
- set (CMAKE_REQUIRED_LIBRARIES )
890
- endif ()
891
-
892
668
if (CLR_CMAKE_TARGET_APPLE )
893
669
set (HAVE__NSGETENVIRON 1 )
894
670
set (DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 1 )
0 commit comments