| 935 | #endif |
| 936 | |
| 937 | txInteger fxWaitSharedChunk(txMachine* the, void* data, txNumber timeout, txSlot* resolveFunction) |
| 938 | { |
| 939 | txInteger result = 1; |
| 940 | if (gxSharedCluster) { |
| 941 | #if mxThreads |
| 942 | txSharedWaiter* waiter; |
| 943 | txSharedWaiter** address; |
| 944 | txSharedWaiter* link; |
| 945 | waiter = c_calloc(1, sizeof(txSharedWaiter)); |
| 946 | if (!waiter) |
| 947 | fxAbort(the, XS_NOT_ENOUGH_MEMORY_EXIT); |
| 948 | waiter->the = the; |
| 949 | waiter->data = data; |
| 950 | mxLockMutex(&gxSharedCluster->waiterMutex); |
| 951 | address = &(gxSharedCluster->first); |
| 952 | while ((link = *address)) |
| 953 | address = &(link->next); |
| 954 | *address = waiter; |
| 955 | |
| 956 | if (resolveFunction) { |
| 957 | mxUnlockMutex(&gxSharedCluster->waiterMutex); |
| 958 | waiter->resolve = *resolveFunction; |
| 959 | fxRemember(the, &waiter->resolve); |
| 960 | #ifdef mxScheduleSharedTimer |
| 961 | waiter->timer = mxScheduleSharedTimer(timeout, 0, (txSharedTimerCallback)fxWaitSharedChunkCallback, &waiter, sizeof(txSharedWaiter*)); |
| 962 | if (!waiter->timer) |
| 963 | fxAbort(the, XS_NOT_ENOUGH_MEMORY_EXIT); |
| 964 | #else |
| 965 | fxAbort(the, XS_DEAD_STRIP_EXIT); |
| 966 | #endif |
| 967 | } |
| 968 | else if (gxSharedCluster->mainThread != mxCurrentThread()) { |
| 969 | txCondition condition; |
| 970 | mxCreateCondition(&condition); |
| 971 | waiter->condition = &condition; |
| 972 | if (timeout == C_INFINITY) { |
| 973 | #if defined(mxUsePOSIXThreads) |
| 974 | while (waiter->data == data) |
| 975 | pthread_cond_wait(&condition, &gxSharedCluster->waiterMutex); |
| 976 | #elif defined(mxUseFreeRTOSTasks) |
| 977 | mxUnlockMutex(&gxSharedCluster->waiterMutex); |
| 978 | ulTaskNotifyTake(pdTRUE, portMAX_DELAY); |
| 979 | mxLockMutex(&gxSharedCluster->waiterMutex); |
| 980 | #else |
| 981 | while (waiter->data == data) |
| 982 | SleepConditionVariableCS(&condition, &gxSharedCluster->waiterMutex, INFINITE); |
| 983 | #endif |
| 984 | } |
| 985 | else { |
| 986 | #if defined(mxUsePOSIXThreads) |
| 987 | struct timespec ts; |
| 988 | timeout += fxDateNow(); |
| 989 | ts.tv_sec = c_floor(timeout / 1000); |
| 990 | ts.tv_nsec = c_fmod(timeout, 1000) * 1000000; |
| 991 | while (waiter->data == data) { |
| 992 | result = (pthread_cond_timedwait(&condition, &gxSharedCluster->waiterMutex, &ts) == ETIMEDOUT) ? 0 : 1; |
| 993 | if (!result) |
| 994 | break; |
no test coverage detected