on master help sign in
Add a timeout to checkMessages
commit3760508ced7d58e61a33be938444d698a877131a authorEdwin Brady <ecb10@st-andrews.ac.uk> dateSat 20 Jun 2015, 23:44 (11 years ago) parent1fd9722
3 files changed+34
libs/base/System/Concurrency/Raw.idr+9 rts/idris_rts.c+23 rts/idris_rts.h+2
libs/base/System/Concurrency/Raw.idr+9
@@ -19,6 +19,15 @@ checkMsgs = do msgs <- foreign FFI_C "idris_checkMessages" (Ptr -> IO Ptr)
1919 null <- nullPtr msgs
2020 return (not null)
2121
22+||| Check for messages in the process inbox
23+||| If no messages, waits for the given number of seconds
24+checkMsgsTimeout : Int -> IO Bool
25+checkMsgsTimeout timeout
26+ = do msgs <- foreign FFI_C "idris_checkMessagesTimeout"
27+ (Ptr -> Int -> IO Ptr) prim__vm timeout
28+ null <- nullPtr msgs
29+ return (not null)
30+
2231||| Check for messages in the process inbox.
2332||| Returns either 'Nothing', if none, or 'Just pid' as pid of sender.
2433listenMsgs : IO (Maybe Ptr)
rts/idris_rts.c+23
@@ -801,6 +801,29 @@ VM* idris_checkMessagesFrom(VM* vm, VM* sender) {
801801 return 0;
802802}
803803
804+VM* idris_checkMessagesTimeout(VM* vm, int delay) {
805+ VM* sender = idris_checkMessagesFrom(vm, NULL);
806+ if (sender != NULL) {
807+ return sender;
808+ }
809+
810+ struct timespec timeout;
811+ int status;
812+
813+ // Wait either for a timeout or until we get a signal that a message
814+ // has arrived.
815+ pthread_mutex_lock(&vm->inbox_block);
816+ timeout.tv_sec = time (NULL) + delay;
817+ timeout.tv_nsec = 0;
818+ status = pthread_cond_timedwait(&vm->inbox_waiting, &vm->inbox_block,
819+ &timeout);
820+ (void)(status); //don't emit 'unused' warning
821+ pthread_mutex_unlock(&vm->inbox_block);
822+
823+ return idris_checkMessagesFrom(vm, NULL);
824+}
825+
826+
804827Msg* idris_getMessageFrom(VM* vm, VM* sender) {
805828 Msg* msg;
806829
rts/idris_rts.h+2
@@ -259,6 +259,8 @@ void idris_sendMessage(VM* sender, VM* dest, VAL msg);
259259VM* idris_checkMessages(VM* vm);
260260// Check whether there are any messages in the queue
261261VM* idris_checkMessagesFrom(VM* vm, VM* sender);
262+// Check whether there are any messages in the queue, and wait if not
263+VM* idris_checkMessagesTimeout(VM* vm, int timeout);
262264// block until there is a message in the queue
263265Msg* idris_recvMessage(VM* vm);
264266// block until there is a message in the queue