You are mixing 3 different aspects: - how to update a UI from a background process - how to maintain a background process over image save/open - how to communicate between the 2
Safe UI updating has to happen using #step or #defer: and should be quick/short as not to block the UI. Although processes survive over image save/open (provided they did not become garbage), this is dangerous as they come up immediately (too soon) and will probably hold external resources (files/sockets/..) that will have changed (and result in a crash). It is better to manage this explicitly using #startUp and #shutDown. Communication between the 2 should be protected using a semaphore. Here is an example of a 'file watcher', a little window that shows the first line of a specific file, updating it every 3 seconds (silly and too resource intensive, it is just a demo). You can edit the file manually to modify the contents of the first line and see it being picked up in Pharo (within 3 seconds). Here is the code as 1 file/class in '_UnpackagedPackage':
MyFileWatcher.st
Description: Binary data
See the class side #initialize for the #startUp and #shutDown registration, sent to all instances as #start and #stop (a bit rude but good enough for the demo). Instance side #initialize sets up the mutex that gets used in the #firstLine and #firstLine: accessors. The actual process is in #run which calls #updateFirstLine The UI updating is in #step which calls #updateFileLineDisplay Subscribing to MorphDeleted via the announcer allows for the process to stop when the window closes. The file watcher window and process survive an image save/open (i.e. they keep on working). HTH, Sven > On 3 Jun 2017, at 15:44, horrido <horrido.hobb...@gmail.com> wrote: > > Okay, let me explain my application... > > It displays a Morphic window containing lines of information that are > updateable in real time on a periodic basis. As I indicated in the original > post, the code skeleton is basically: > > initA > a := ((StringMorph contents: '####') color: Color white) position: (0@0). > m addMorph: a > > initialize > f := Form fromFileNamed: 'hot_air_balloon_mysticmorning.jpg'. > m := ImageMorph new. > m form: f. > self initA. > m openInWindowLabeled: 'Cranky'. > delay := (Delay forSeconds: 5). > [ [ true ] whileTrue: [ a contents: 0 asString. delay wait ] fork > > Imagine that #initA creates many such StringMorphs, each displaying a > different kind of information. > > In the endless loop, imagine that instead of 'a contents: 0 asString', I'm > updating all of the StringMorphs I created in #initA. > > The need to do this in a separate thread is to prevent Pharo from being > completely frozen during the 'delay wait', which is practically all the > time! > > Now, I did try Hilaire's suggestion to use Morphic's step protocol instead. > But in my test scenario of closing the app/saving and exiting the > image/restarting the image, repeatedly (in may take 10-20 times), it still > causes the occasional segmentation fault. > > So if the problem is updating a structure in the main thread from another > process, then why did Hilaire's suggestion not solve the problem? > > It seems to me, then, either way, it's an issue of multithreading...whether > my way or Hilaire's way. > > > > Sven Van Caekenberghe-2 wrote >> Hi Horrido, >> >> It is very hard to follow what you are exactly doing or trying to do. >> >> Here is the simplest example I can think of that updates something in >> Morphic on a regular basis. >> >> StringMorph subclass: #MyClock >> instanceVariableNames: '' >> classVariableNames: '' >> package: '_UnpackagedPackage' >> >> MyClock>>#initialize >> super initialize. >> self updateClock >> >> MyClock>>#step >> self updateClock >> >> MyClock>>#updateClock >> self contents: Time now printString >> >> MyClock class>>#open >> "self open" >> >> ^ self new openInWindow >> >> This inherits #stepTime as 1 second. If I open such a window and save my >> image, it is still there when the image is restarted, with the clock still >> working. >> >> Updating (data structures in) the main UI process from another process is >> dangerous. Saving such constructs is even more dangerous. >> >> HTH, >> >> Sven >> >>> On 2 Jun 2017, at 15:54, horrido < > >> horrido.hobbies@ > >> > wrote: >>> >>> Sorry, I could be mistaken. I just checked my notes. The *0 asString* >>> test >>> failed once, but I've not been able to replicate it. I might've been >>> working >>> with an unclean image. >>> >>> So perhaps it is related to Morphic, after all. >>> >>> >>> horrido wrote >>>> Yup, they all fail. Interesting that >>> * >>>> 0 asString >>> * >>>> fails. This means it has NOTHING to do with Morphic (or Morphic being >>>> thread-unsafe). >>>> >>>> Ben Coman wrote >>>>> On Wed, May 31, 2017 at 10:23 PM, horrido < >>> >>>>> horrido.hobbies@ >>> >>>>> > wrote: >>>>> >>>>> Can you try a few other variations... >>>>> [ [ true ] whileTrue: [ 0 asString. delay wait ] fork. >>>>> [ [ true ] whileTrue: [ a contents: '0'. delay wait ] fork. >>>>> [ [ true ] whileTrue: [ a contents: '0'. ] forkAt: 20. >>>>> >>>>> cheers -ben >>> >>> >>> >>> >>> >>> -- >>> View this message in context: >>> http://forum.world.st/Morphic-or-forking-bug-tp4948727p4948984.html >>> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com. > > > > > > -- > View this message in context: > http://forum.world.st/Morphic-or-forking-bug-tp4948727p4949166.html > Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.