--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/GDBEventDispatcher.st Tue Mar 09 20:49:55 2021 +0000
@@ -0,0 +1,213 @@
+"
+jv:libgdbs - GNU Debugger Interface Library
+Copyright (C) 2015-now Jan Vrany
+Copyright (C) 2021 LabWare
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'jv:libgdbs' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#GDBEventDispatcher
+ instanceVariableNames:'queue lock notifier process stopping announcer1 announcer2'
+ classVariableNames:''
+ poolDictionaries:'GDBDebugFlags'
+ category:'GDB-Private'
+!
+
+!GDBEventDispatcher class methodsFor:'documentation'!
+
+copyright
+"
+jv:libgdbs - GNU Debugger Interface Library
+Copyright (C) 2015-now Jan Vrany
+Copyright (C) 2021 LabWare
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!GDBEventDispatcher class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+! !
+
+!GDBEventDispatcher methodsFor:'accessing'!
+
+process
+ ^ process
+! !
+
+!GDBEventDispatcher methodsFor:'dispatching'!
+
+notify
+ "Notify dispatcher that there may be some new
+ events in the queue."
+
+ notifier signal.
+
+ "Created: / 02-10-2018 / 14:24:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+start
+ self assert: queue notNil.
+ self assert: lock notNil.
+
+ process isNil ifTrue:[
+ stopping := false.
+ process := [
+ TraceEvents ifTrue:[
+ Logger log: 'event loop: starting' severity: #trace facility: 'GDB'
+ ].
+ self dispatch.
+ ] newProcess.
+ process name:('GDB Event dispatcher').
+ process priority:Processor userBackgroundPriority.
+ process addExitAction:[
+ process := nil.
+ stopping := nil.
+ TraceEvents ifTrue:[
+ Logger log: 'event loop: terminated' severity: #trace facility: 'GDB'
+ ].
+ ].
+ process resume.
+ ].
+
+ "Created: / 02-10-2018 / 14:25:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (format): / 02-10-2018 / 16:34:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stop
+ stopping := true.
+ notifier signal.
+
+ "Created: / 02-10-2018 / 14:25:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBEventDispatcher methodsFor:'initialization'!
+
+initialize
+ "Invoked when a new instance is created."
+
+ super initialize.
+ notifier := Semaphore new
+
+ "Modified: / 02-10-2018 / 14:13:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setAnnouncer1: anAnnouncer
+ announcer1 := anAnnouncer
+
+ "Created: / 02-10-2018 / 14:21:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setAnnouncer2: anAnnouncer
+ announcer2 := anAnnouncer
+
+ "Created: / 02-10-2018 / 14:21:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setLock: aRecursionLock
+ lock := aRecursionLock
+
+ "Created: / 02-10-2018 / 14:20:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setQueue: anOrderedCollection
+ queue := anOrderedCollection.
+
+ "Created: / 02-10-2018 / 14:20:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBEventDispatcher methodsFor:'private'!
+
+dispatch
+ "raise an error: this method should be implemented (TODO)"
+
+ [
+ | eventQueueEmpty |
+
+ eventQueueEmpty := false.
+ [ eventQueueEmpty ] whileFalse:[
+ | event |
+
+ event := nil.
+ lock
+ critical:[
+ eventQueueEmpty := queue isEmpty.
+ eventQueueEmpty ifFalse:[
+ event := queue removeFirst.
+ ]
+ ].
+ eventQueueEmpty ifFalse:[
+ (AbortOperationRequest , AbortAllOperationRequest)
+ ignoreIn:[ self dispatchEvent:event. ]
+ ].
+ ].
+ stopping == true ifTrue:[
+ ^ self.
+ ].
+ notifier wait.
+ ] loop.
+
+ "Created: / 02-06-2014 / 22:51:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 14-01-2018 / 21:54:32 / jv"
+ "Modified: / 02-10-2018 / 13:35:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+dispatchEvent:aGDBEvent
+ TraceEvents ifTrue:[
+ Logger
+ log:('event loop: broadcasting %1 (%2)' bindWith:aGDBEvent class name
+ with:aGDBEvent token)
+ severity:#trace
+ facility:'GDB'
+ originator:self
+ attachment:aGDBEvent
+ ].
+ announcer1 notNil ifTrue:[
+ announcer1 announce:aGDBEvent.
+ ].
+ announcer2 notNil ifTrue:[
+ announcer2 announce:aGDBEvent
+ ].
+
+ "Created: / 02-06-2014 / 22:58:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 02-10-2018 / 14:36:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBEventDispatcher class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+