The script comes in two versions, both of which do the same thing and differ only in the names of the ports.
Three boxes are displayed: the left one for sending, the middle one for receiving, and the button on the right can be used to re-create the port.
The left box turns blue immediately before SendMessage() and then turns green again if successful, so it flickers, but this way you can see when SendMessage() freezes. The middle one turns red if no messages arrive for 0.5 seconds.
The script runs without issues on Windows; on 32-bit ARM (Raspberry) it mostly freezes after a few seconds, and on Linux Mint (x64) after a few minutes.
Code: Select all
@DISPLAY {Width = 400, Height = 150, Color = 0x666666, Layers=True}
; create/recreate port
Function p_IPCInit()
CreatePort("x") ; replace port
Sleep(1000) ; trigger error color of receiver
Local err= ?CreatePort(gMPortName$) ; restore own port
If err<>#ERR_NONE
NPrint("CreatePort failed:\n"..GetErrorName(err))
SetLayerStyle("box1", {color=#BLACK})
SetLayerStyle("box3", {color=#BLACK})
Else
InstallEventHandler({OnUserMessage = p_EventIPCMessage})
SetLayerStyle("box3", {color=0x00ee22})
Sleep(500)
SetLayerStyle("box3", {color=#GRAY})
EndIf
EndFunction
; ipc message
Function p_EventIPCMessage(msg)
SetLayerStyle("box2", {color=#GREEN}) ; message received
p_InitReceiveTimeout()
Switch msg.action
Case "OnUserMessage"
Local argstable=SplitStr(msg.args, "\0")
Switch msg.command
Case "TEST"
If ToNumber(argstable[0])<>gReceiveCounter
; no match
gReceiveErrors=gReceiveErrors+1
gReceiveCounter=argstable[0] ; sync again
EndIf
gReceiveCounter=gReceiveCounter+1
Default
; should not come
gReceiveErrors=gReceiveErrors+1
EndSwitch
EndSwitch
SetLayerStyle("ReceiveCounter", {Text=gReceiveCounter})
SetLayerStyle("ReceiveErrors", {Text=gReceiveErrors})
EndFunction
; set receive timeout
Function p_InitReceiveTimeout()
If HaveObject(#TIMEOUT, 1) Then ClearTimeout(1)
SetTimeout(1, Function()
SetLayerStyle("box2", {color=#RED}) ; no message for 500ms
EndFunction,
500)
EndFunction
; button event
Function p_EventButton(bmsg)
Switch bmsg.action
Case "OnMouseOver":
SetLayerStyle("box3", {color=0xaaaaaa})
Case "OnMouseOut":
SetLayerStyle("box3", {color=#GRAY})
Case "OnMouseDown":
SetLayerStyle("box3", {color=#YELLOW})
Case "OnMouseUp":
SetLayerStyle("box3", {color=#RED})
p_IPCInit()
EndSwitch
EndFunction
; interval function (try to send)
Function p_EventCheckConnection()
SetLayerStyle("box1", {color=#BLUE})
Local err= ?SendMessage(gSPortName$, "TEST", ToString(gSendCounter))
If err=#ERR_NONE
gSendCounter=gSendCounter+1
SetLayerStyle("box1", {color=#GREEN})
Else
SetLayerStyle("box1", {color=#RED})
If gSendCounter>0 ; wait for running receiver
gSendErrors=gSendErrors+1
EndIf
EndIf
SetLayerStyle("SendCounter", {Text=gSendCounter})
SetLayerStyle("SendErrors", {Text=gSendErrors})
EndFunction
SetFillStyle(#FILLCOLOR)
Local left=20
Box(left+50, 50, 50, 50, 0x888888, {Name="box1"}) ; send state
SetInterval(1, p_EventCheckConnection, 50)
Box(left+175, 50, 50, 50, 0x888888, {Name="box2"}) ; receive state
p_InitReceiveTimeout()
Box(left+300, 50, 50, 50, 0x888888, {Name="box3"}) ; port reset button
MakeButton(1, #LAYERBUTTON, "box3", {OnMouseOver=p_EventButton, OnMouseOut=p_EventButton, OnMouseDown=p_EventButton, OnMouseUp=p_EventButton})
gSPortName$="IPCS"
gMPortName$="IPCM"
gSendCounter=0
gSendErrors=0
gReceiveCounter=0
gReceiveErrors=0
TextOut(left+50, 20, "send")
TextOut(left+175, 20, "receive")
TextOut(0, 130, "errors")
TextOut(0, 120, "counter")
TextOut(left+50, 120, gSendCounter, {Name="SendCounter", Color=#WHITE})
TextOut(left+50, 130, gSendErrors, {Name="SendErrors", Color=#WHITE})
TextOut(left+175, 120, gReceiveCounter, {Name="ReceiveCounter", Color=#WHITE})
TextOut(left+175, 130, gReceiveErrors, {Name="ReceiveErrors", Color=#WHITE})
p_IPCInit()
Repeat
WaitEvent
Forever
Code: Select all
@DISPLAY {Width = 400, Height = 150, Color = 0x222222, Layers=True}
; create/recreate port
Function p_IPCInit()
CreatePort("x") ; replace port
Sleep(1000) ; trigger error color of receiver
Local err= ?CreatePort(gSPortName$) ; restore own port
If err<>#ERR_NONE
NPrint("CreatePort failed:\n"..GetErrorName(err))
SetLayerStyle("box1", {color=#BLACK})
SetLayerStyle("box3", {color=#BLACK})
Else
InstallEventHandler({OnUserMessage = p_EventIPCMessage})
SetLayerStyle("box3", {color=0x00ee22})
Sleep(500)
SetLayerStyle("box3", {color=#GRAY})
EndIf
EndFunction
; ipc message
Function p_EventIPCMessage(msg)
SetLayerStyle("box2", {color=#GREEN}) ; message received
p_InitReceiveTimeout()
Switch msg.action
Case "OnUserMessage"
Local argstable=SplitStr(msg.args, "\0")
Switch msg.command
Case "TEST"
If ToNumber(argstable[0])<>gReceiveCounter
; no match
gReceiveErrors=gReceiveErrors+1
gReceiveCounter=argstable[0] ; sync again
EndIf
gReceiveCounter=gReceiveCounter+1
Default
; should not come
gReceiveErrors=gReceiveErrors+1
EndSwitch
EndSwitch
SetLayerStyle("ReceiveCounter", {Text=gReceiveCounter})
SetLayerStyle("ReceiveErrors", {Text=gReceiveErrors})
EndFunction
; set receive timeout
Function p_InitReceiveTimeout()
If HaveObject(#TIMEOUT, 1) Then ClearTimeout(1)
SetTimeout(1, Function()
SetLayerStyle("box2", {color=#RED}) ; no message for 500ms
EndFunction,
500)
EndFunction
; button event
Function p_EventButton(bmsg)
Switch bmsg.action
Case "OnMouseOver":
SetLayerStyle("box3", {color=0xaaaaaa})
Case "OnMouseOut":
SetLayerStyle("box3", {color=#GRAY})
Case "OnMouseDown":
SetLayerStyle("box3", {color=#YELLOW})
Case "OnMouseUp":
SetLayerStyle("box3", {color=#RED})
p_IPCInit()
EndSwitch
EndFunction
; interval function (try to send)
Function p_EventCheckConnection()
SetLayerStyle("box1", {color=#BLUE})
Local err= ?SendMessage(gMPortName$, "TEST", ToString(gSendCounter))
If err=#ERR_NONE
gSendCounter=gSendCounter+1
SetLayerStyle("box1", {color=#GREEN})
Else
SetLayerStyle("box1", {color=#RED})
If gSendCounter>0 ; wait for running receiver
gSendErrors=gSendErrors+1
EndIf
EndIf
SetLayerStyle("SendCounter", {Text=gSendCounter})
SetLayerStyle("SendErrors", {Text=gSendErrors})
EndFunction
SetFillStyle(#FILLCOLOR)
Local left=20
Box(left+50, 50, 50, 50, 0x888888, {Name="box1"}) ; send state
SetInterval(1, p_EventCheckConnection, 50)
Box(left+175, 50, 50, 50, 0x888888, {Name="box2"}) ; receive state
p_InitReceiveTimeout()
Box(left+300, 50, 50, 50, 0x888888, {Name="box3"}) ; port reset button
MakeButton(1, #LAYERBUTTON, "box3", {OnMouseOver=p_EventButton, OnMouseOut=p_EventButton, OnMouseDown=p_EventButton, OnMouseUp=p_EventButton})
gSPortName$="IPCS"
gMPortName$="IPCM"
gSendCounter=0
gSendErrors=0
gReceiveCounter=0
gReceiveErrors=0
TextOut(left+50, 20, "send")
TextOut(left+175, 20, "receive")
TextOut(0, 130, "errors")
TextOut(0, 120, "counter")
TextOut(left+50, 120, gSendCounter, {Name="SendCounter", Color=#WHITE})
TextOut(left+50, 130, gSendErrors, {Name="SendErrors", Color=#WHITE})
TextOut(left+175, 120, gReceiveCounter, {Name="ReceiveCounter", Color=#WHITE})
TextOut(left+175, 130, gReceiveErrors, {Name="ReceiveErrors", Color=#WHITE})
p_IPCInit()
Repeat
WaitEvent
Forever