Re: [m-users.] Calling exit(3) from a foreign predicate
Volker Wysk <[email protected]> Thu, 25 Jan 2024 15:24:51 +0100
| Newsgroups | gmane.comp.lang.mercury.general |
|---|---|
| Message-ID | <[email protected]> |
Am Donnerstag, dem 25.01.2024 um 07:53 +0000 schrieb Sean Charles (emacstheviking): > What a module accessible flag for global control then I guess? > > :- module foo. > > :- pred is_exit_requested. > > :- implementation. > > :- mutable (stop_flag, bool, no, ground, [...whats your app needs...]). > > :- pragma promise_pure(stop_threads/0). > :- pred stop_threads :- > impure set_stop_flag(yes). > > > :- pragma promise_pure(iis_exit_requested/0). > :- pred is_exit_requested is semidet. > is_exit_requested :- > semipure get_stop_flag(yes). > > > then inside your threads you can just called foo.is_exit_requested ? > This is off the top of my head, so I have probably made a few m istakes, > it's early and I've not had my porridge yet, those are my excuses! > > That's kind of what I was hinting at nefpre; external control, but I > assumed you were passing two-way control structures but if the threads > have no ears then thisd might be the solution / a solution? > > Good luck VOlker, you always figure out! Thanks for your consideration. But the infrastructure for shutting down the threads is already in place (except for one piece). It works like this: There's a master thread (the main program), which spawns a feeder thread and a number of worker threads. The feeder is connected to the workers and to master by a channel each. It feeds work items (paths to files) to the workers. Those do something with it. They bring the database up to date with respect to the path. They also (re)calculate hashes of the files, when needed. The workers send the work results (hashes) to master, which does something with it. The feeder also sends messages to master about the succession in which the files occur. And when all work has been feeded, the feeder sends an "end" message to all workers. This message causes the worker to send an "end" message to master, on his part, and to leave the predicate which it has been started with. Meaning the worker terminates. Master does something with the received work results. It depends on which operation has been chosen. Such as "print the hashes of the files". When there happens a database error, the whole process, meaning all threads, should be terminated. It can occur in one worker, or occur in all workers (such as authentication failure when establishing the database connection). Now, in order terminate the process, I can go the easy way and just call exit(3). The downside is, that the Mercury shutdown isn't carried out (except for what exit() does). The other way would be to cause the threads (workers and feeder) to terminate themselves. The feeder would need to be instructed to stop feeding and terminate. It should send "end" messages to all workers, and terminate itself afters. Then master needs to collect all messages (work results/errors), which are still pending. And it needs to collect and count the "end" messages from the workers to master, so it knows when all workers have terminated. Informing the feeder to stop feeding, could be done with an mvar (thread.mvar module). The downside of this is, that it's more complicated than the easy way. (It's hard to debug inter-thread-communication). And it would mean waiting until all workers are done with their work. That can take a long time, when a worker is calculating the hash of a large file... So, which way should I take? I guess it depends on how bad it is to terminate the process the hard way by calling exit(3) and not calling mercury_runtime_terminate(). I hope I haven't bored you. Cheers, Volker _______________________________________________ users mailing list [email protected] https://lists.mercurylang.org/listinfo/users