Re: Translating C headers to D: How do I compile it?

2020-06-27 Thread mw via Digitalmars-d-learn

On Sunday, 28 June 2020 at 04:59:12 UTC, Kirill wrote:
Hello. I am learning how to translate C headers to D. But how 
do I compile it? I am stuck with this.


You can try just to use dpp:

https://code.dlang.org/packages/dpp

instead of doing the translation manually.




Re: Translating C headers to D: How do I compile it?

2020-06-27 Thread rikki cattermole via Digitalmars-d-learn

On 28/06/2020 4:59 PM, Kirill wrote:

module something;

extern(C)

int add(int a, int b);





Compile as static library some.c, add to command line of dmd.

Should be this simple more or less, depending on compilers and target 
involved.




Re: Translating C headers to D: How do I compile it?

2020-06-27 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 28 June 2020 at 04:59:12 UTC, Kirill wrote:
Hello. I am learning how to translate C headers to D. But how 
do I compile it? I am stuck with this.


I have 4 files in the same directory: main.d, something.d, 
some.h, some.c


some.h:
//header guards
int add(int a, int b);

some.c:
#include "some.h"
int add(int a, int b) { return a+b; }

something.d:
module something;
int add(int a, int b);


This should be extern(C) int add(int a, int b). The extern(C) 
tells the D compiler to use the standard C calling convention 
when calling that function.




main.d:
import std.stdio: writeln;
import something;

void main() { writeln("5+7=", add(5, 7); }

How do I compile this correctly?

Thank you for your time.


The C file and the header do not need to be (and arguably 
shouldn't be) in the same directory as the D files. Use a C 
compiler to compile the C file to an object file or into a static 
library. Assuming you're using DMD, then on Windows you'll want 
to use the Microsoft compiler (cl) which is part of the Microsoft 
Build Tools distribution and Visual Studio. Otherwise, you'll 
need the Digital Mars C and C++ compiler. On other platforms, GCC 
or clang will be fine. If you don't know how to compile C 
programs, there's plenty of information online for all the major 
compilers.



Then, when you compile your D program, you'll need to link with 
the object file or the static library you compiled with the C 
compiler. On Windows, if you used Digital Mars C (dmc), then you 
won't need to pass any special compiler flags if you are calling 
DMD directly. If you used the MS compiler, you'll need to pass 
either -m32mscoff for 32-bit, or -m64 for 64-bit.





Translating C headers to D: How do I compile it?

2020-06-27 Thread Kirill via Digitalmars-d-learn
Hello. I am learning how to translate C headers to D. But how do 
I compile it? I am stuck with this.


I have 4 files in the same directory: main.d, something.d, 
some.h, some.c


some.h:
//header guards
int add(int a, int b);

some.c:
#include "some.h"
int add(int a, int b) { return a+b; }

something.d:
module something;
int add(int a, int b);

main.d:
import std.stdio: writeln;
import something;

void main() { writeln("5+7=", add(5, 7); }

How do I compile this correctly?

Thank you for your time.




Re: foreach iterator with closure

2020-06-27 Thread Ali Çehreli via Digitalmars-d-learn

On 6/27/20 8:19 PM, Denis wrote:

> Is it possible to write an iterator

It is arguable whether D's ranges are iterators but if nouns are useful, 
we call them ranges. :) (Iterators can be written in D as well and then 
it would really be confusing.)


>struct letters {
>  string str;
>  int pos = 0;
>  char front() { return str[pos]; }
>  void popFront() { pos ++; }
>  bool empty() {
>if (pos == 0) writeln(`BEGIN`);
>else if (pos == str.length) writeln("\nEND");
>return pos == str.length; }}
>
>void main() {
>  foreach (letter; letters(`hello`)) {
>write(letter, ' '); }
>  writeln(); }
>
> The obvious problems with this code include:
>
> (1) The user can pass a second argument, which will set the initial
> value of pos.

That problem can be solved by a constructor that takes a single string. 
Your BEGIN code would normally go there as well. And END goes into the 
destructor:


struct letters {
this(string str) {
this.str = str;
this.pos = 0;  // Redundant
writeln(`BEGIN`);
}

~this() {
writeln("\nEND");
}

// [...]
}

Note: You may want to either disallow copying of your type or write copy 
constructor that does the right thing:


  https://dlang.org/spec/struct.html#struct-copy-constructor

However, it's common to construct a range object by a function. The 
actual range type can be kept as an implementation detail:


struct Letters {  // Note capital L
  // ...
}

auto letters(string str) {
  // ...
  return Letters(str);
}

struct Letter can be a private type of its module or even a nested 
struct inside letters(), in which case it's called a "Voldemort type".


Ali



foreach iterator with closure

2020-06-27 Thread Denis via Digitalmars-d-learn
Is it possible to write an iterator that does the following, 
using a struct and some functions?


 - Operates in a foreach loop
 - Has BEGIN-like and END-like blocks or functions that are 
executed automatically, before and after the iterations
 - Initializes variables in the BEGIN block that are used in the 
other two. These variables are for internal use only, i.e. must 
not be accessible to the user of the foreach loop


I'd like to use the simplest solution while keeping the code 
clean. As a starting point, here's a contrived example using a 
struct with a range-style iterarator:


  import std.stdio;

  struct letters {
string str;
int pos = 0;
char front() { return str[pos]; }
void popFront() { pos ++; }
bool empty() {
  if (pos == 0) writeln(`BEGIN`);
  else if (pos == str.length) writeln("\nEND");
  return pos == str.length; }}

  void main() {
foreach (letter; letters(`hello`)) {
  write(letter, ' '); }
writeln(); }

The obvious problems with this code include:

(1) The user can pass a second argument, which will set the 
initial value of pos. This must not be allowed. (The real code 
will need to initialize a half dozen internal-only variables, and 
do some additional work, before the looping starts.)


(2) Sticking the code for the BEGIN and END blocks into the 
empty() function is ugly.


Can this iterator be written using a range-style struct? Or is 
something more complicated needed, like an OO solution?


I should add that the final version of this will be put in a 
separate module, possibly in a library, so I can call it from 
many programs. Not sure if that might help simplify things.


Thanks for your guidance.


Re: mixin template compile-time compute declared name

2020-06-27 Thread NonNull via Digitalmars-d-learn

On Saturday, 27 June 2020 at 21:23:10 UTC, Adam D. Ruppe wrote:

On Saturday, 27 June 2020 at 21:10:59 UTC, NonNull wrote:
Is it possible to use a template to declare something whose 
name is computed at compile time?


You'd have to string mixin the contents inside the mixin 
template.


Worked! Thank you!!


Re: mixin template compile-time compute declared name

2020-06-27 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 27 June 2020 at 21:10:59 UTC, NonNull wrote:
Is it possible to use a template to declare something whose 
name is computed at compile time?


You'd have to string mixin the contents inside the mixin template.


mixin template compile-time compute declared name

2020-06-27 Thread NonNull via Digitalmars-d-learn



Want

mixin mytemplate!("foo", .);

to be able to declare names dependent upon the text foo in the 
context it is used.


For example declaring

enum x_foo = ;
blah foo_value = ;
.
.
.
.

Is it possible to use a template to declare something whose name 
is computed at compile time?






Re: How to send ownerTid into a parallel foreach loop?

2020-06-27 Thread Kagamin via Digitalmars-d-learn

On Saturday, 27 June 2020 at 07:51:21 UTC, adnan338 wrote:

On Saturday, 27 June 2020 at 07:31:56 UTC, Kagamin wrote:
std.concurrency is for noninteractive appications, the 
approach with gui timer was the correct one.


Thank you. That works but my progress bar is sometimes getting 
stuck because of a possible data race.
See 
https://forum.dlang.org/post/gacweulvbyorkseti...@forum.dlang.org


Sometimes? In that code you write the progress variable only 
once, so it doesn't change after that. Nothing else can possibly 
happen there with or without multithreading.


Re: Garbage collection

2020-06-27 Thread James Gray via Digitalmars-d-learn

On Saturday, 27 June 2020 at 14:49:34 UTC, James Gray wrote:

On Saturday, 27 June 2020 at 14:12:09 UTC, kinke wrote:

[...]


Thank you for doing this. I hope my example doesn't obscure 
what you show here.

(I borrowed some of your code).

[...]


In case it helps, setting all the next and previous pointers in 
the link list to null allows the garbage collector to collect in 
the above code.


Re: Garbage collection

2020-06-27 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 27 June 2020 at 16:03:12 UTC, kinke wrote:
On Saturday, 27 June 2020 at 15:27:34 UTC, Stanislav Blinov 
wrote:



Hrm... What happens if you call collect() twice?


Nothing changes, even when collecting 5 times at the end of 
each iteration. In the filed testcase, I've extracted the stack 
ref to a dedicated function, so that there really shouldn't be 
any refs on the stack (this is unoptimized code after all...).


Here on Linux, the double collection results in this output:

  GC stats: 0M used, 0M free, 0M total
Starting
  string size: 943M
  GC stats: 0M used, 2306M free, 2306M total
Starting
  string size: 943M
  GC stats: 0M used, 2306M free, 2306M total
Starting
  string size: 943M
  GC stats: 0M used, 2306M free, 2306M total
Starting
  string size: 943M
  GC stats: 0M used, 2306M free, 2306M total


Re: Garbage collection

2020-06-27 Thread kinke via Digitalmars-d-learn

On Saturday, 27 June 2020 at 15:27:34 UTC, Stanislav Blinov wrote:

On Saturday, 27 June 2020 at 14:12:09 UTC, kinke wrote:

Note that I explicitly clear the `str` slice before 
GC.collect(), so that the stack shouldn't contain any refs to 
the fat string anymore.


Hrm... What happens if you call collect() twice?


Nothing changes, even when collecting 5 times at the end of each 
iteration. In the filed testcase, I've extracted the stack ref to 
a dedicated function, so that there really shouldn't be any refs 
on the stack (this is unoptimized code after all...).


Re: Garbage collection

2020-06-27 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 27 June 2020 at 14:12:09 UTC, kinke wrote:

Note that I explicitly clear the `str` slice before 
GC.collect(), so that the stack shouldn't contain any refs to 
the fat string anymore.


Hrm... What happens if you call collect() twice?


Re: Garbage collection

2020-06-27 Thread James Gray via Digitalmars-d-learn

On Saturday, 27 June 2020 at 14:12:09 UTC, kinke wrote:

On Saturday, 27 June 2020 at 10:08:15 UTC, James Gray wrote:

have run into a memory leak


Something seems really off indeed. I've run this on Win64 with 
DMD (2.092) and LDC (1.22), without any extra cmdline options:


-
import core.memory;
import core.stdc.stdio;
import std.range;
import std.format;

auto f(R)(R r) { return format("%s", r); }

int toMB(ulong size) { return cast(int) (size / 1048576.0 + 
0.5); }


void printGCStats()
{
const stats = GC.stats;
const used = toMB(stats.usedSize);
const free = toMB(stats.freeSize);
const total = toMB(stats.usedSize + stats.freeSize);
printf("  GC stats: %dM used, %dM free, %dM total\n", used, 
free, total);

}

void main()
{
printGCStats();

while (true)
{
puts("Starting");
string str = f(iota(100_000_000));
printf("  string size: %dM\n", toMB(str.length));
str = null;
GC.collect();
printGCStats();
}
}
-

Output with DMD (no change with the precise GC via 
`--DRT-gcopt=gc:precise`):

-
  GC stats: 0M used, 1M free, 1M total
Starting
  string size: 943M
  GC stats: 1168M used, 1139M free, 2306M total
Starting
  string size: 943M
  GC stats: 1168M used, 2456M free, 3623M total
Starting
  string size: 943M
  GC stats: 1168M used, 2456M free, 3623M total
Starting
  string size: 943M
  GC stats: 1168M used, 2456M free, 3623M total
Starting
  string size: 943M
  GC stats: 1168M used, 2456M free, 3623M total
-

With LDC:
-
  GC stats: 0M used, 1M free, 1M total
Starting
  string size: 943M
  GC stats: 1168M used, 1139M free, 2306M total
Starting
  string size: 943M
  GC stats: 2335M used, 1288M free, 3623M total
Starting
  string size: 943M
  GC stats: 2335M used, 2605M free, 4940M total
Starting
  string size: 943M
  GC stats: 2335M used, 2605M free, 4940M total
Starting
  string size: 943M
  GC stats: 2335M used, 2605M free, 4940M total
-

Note that I explicitly clear the `str` slice before 
GC.collect(), so that the stack shouldn't contain any refs to 
the fat string anymore.


Thank you for doing this. I hope my example doesn't obscure what 
you show here.

(I borrowed some of your code).

I have produced something which essentially reproduces my problem.

---
import std.range;
import std.algorithm;
import std.format;
import std.stdio;
import core.thread;
import core.memory;


struct Node {
 Node* next;
 Node* prev;
 ulong val;
}

Node* insertAfter(Node* cur, ulong val) {
 Node* node = new Node;
 if (cur != null) {
  node.next = cur.next;
  node.prev = cur;
  cur.next = node;
  node.next.prev = node;
 }
 else {
  node.next = node;
  node.prev = node;
 }
 node.val = val;
 return node;
}

int toMB(ulong size) { return cast(int) (size / 1048576.0 + 0.5); 
}


void printGCStats()
{
 const stats = GC.stats;
 const used = toMB(stats.usedSize);
 const free = toMB(stats.freeSize);
 const total = toMB(stats.usedSize + stats.freeSize);
 writef("  GC stats: %dM used, %dM free, %dM total\n", used, 
free, total);

}


void main()
{
 while(true)
 {
  printGCStats();
  writeln("Starting");
  Node* dll;
  dll = iota(2).fold!((c,x)=>insertAfter(c,x))(dll);
  writef("Last element %s\n", dll.val);
  dll = null;
  writeln("Done");
  GC.collect();
  GC.minimize();
  Thread.sleep( dur!("msecs")( 1 ) );
 }
}
--
With DMD this produces:

  GC stats: 0M used, 0M free, 0M total
Starting
Last element 1
Done
  GC stats: 6104M used, 51M free, 6155M total
Starting
Last element 1
Done
  GC stats: 12207M used, 28M free, 12235M total

With LDC2 this produces:

  GC stats: 0M used, 0M free, 0M total
Starting
Last element 1
Done
  GC stats: 6104M used, 51M free, 6155M total
Starting
Last element 1
Done
  GC stats: 12207M used, 28M free, 12235M total







Re: Garbage collection

2020-06-27 Thread kinke via Digitalmars-d-learn

=> https://issues.dlang.org/show_bug.cgi?id=20983


Re: Garbage collection

2020-06-27 Thread kinke via Digitalmars-d-learn

On Saturday, 27 June 2020 at 10:08:15 UTC, James Gray wrote:

have run into a memory leak


Something seems really off indeed. I've run this on Win64 with 
DMD (2.092) and LDC (1.22), without any extra cmdline options:


-
import core.memory;
import core.stdc.stdio;
import std.range;
import std.format;

auto f(R)(R r) { return format("%s", r); }

int toMB(ulong size) { return cast(int) (size / 1048576.0 + 0.5); 
}


void printGCStats()
{
const stats = GC.stats;
const used = toMB(stats.usedSize);
const free = toMB(stats.freeSize);
const total = toMB(stats.usedSize + stats.freeSize);
printf("  GC stats: %dM used, %dM free, %dM total\n", used, 
free, total);

}

void main()
{
printGCStats();

while (true)
{
puts("Starting");
string str = f(iota(100_000_000));
printf("  string size: %dM\n", toMB(str.length));
str = null;
GC.collect();
printGCStats();
}
}
-

Output with DMD (no change with the precise GC via 
`--DRT-gcopt=gc:precise`):

-
  GC stats: 0M used, 1M free, 1M total
Starting
  string size: 943M
  GC stats: 1168M used, 1139M free, 2306M total
Starting
  string size: 943M
  GC stats: 1168M used, 2456M free, 3623M total
Starting
  string size: 943M
  GC stats: 1168M used, 2456M free, 3623M total
Starting
  string size: 943M
  GC stats: 1168M used, 2456M free, 3623M total
Starting
  string size: 943M
  GC stats: 1168M used, 2456M free, 3623M total
-

With LDC:
-
  GC stats: 0M used, 1M free, 1M total
Starting
  string size: 943M
  GC stats: 1168M used, 1139M free, 2306M total
Starting
  string size: 943M
  GC stats: 2335M used, 1288M free, 3623M total
Starting
  string size: 943M
  GC stats: 2335M used, 2605M free, 4940M total
Starting
  string size: 943M
  GC stats: 2335M used, 2605M free, 4940M total
Starting
  string size: 943M
  GC stats: 2335M used, 2605M free, 4940M total
-

Note that I explicitly clear the `str` slice before GC.collect(), 
so that the stack shouldn't contain any refs to the fat string 
anymore.


Re: Arduino and MCU Support

2020-06-27 Thread Dylan Graham via Digitalmars-d-learn

On Friday, 26 June 2020 at 09:30:15 UTC, Dukc wrote:

On Thursday, 25 June 2020 at 03:00:04 UTC, Dylan Graham wrote:
I'm currently making an automatic transmission controller with 
Arduino. C++ just has too many traps that I keep falling into. 
Since stability is critical (if the code screws up at 100km/h 
I'm dead), I'd rather use a sane language like D.


No, don't! Regardless of the language, you should never trust 
your safety on one single program. See 
https://www.digitalmars.com/articles/b39.html


Realistically, doing such a controller cannot be one man/woman 
endeavour.


Thank you for the article. It was an intriguing read.

I don't really have any capacity to implement multiple concurrent 
programs given how limited the hardware is.


What I do have is a "pipeline" of modules that have their own 
checks to mitigate logical errors.


The transmission also has a mechanical backup should the 
electronics fail.


What I meant more so was creature comforts D provides that you 
begin missing when you revert to C++ -- something that can assist 
me in avoiding certain classes of bugs, which is what was 
referring to in my original message and I fear the most.


I have a running controller that even interacts with car's stock 
computers and is passing real world tests at current. Automotive 
engineering is more approachable than it first appears.




Re: Garbage collection

2020-06-27 Thread James Gray via Digitalmars-d-learn

On Saturday, 27 June 2020 at 12:07:19 UTC, Stanislav Blinov wrote:

On Saturday, 27 June 2020 at 11:35:12 UTC, Arafel wrote:

If you are using linux, have in mind that the memory is often 
not returned to the OS even after a (libc) free.


That's a good observation. Although a GC implementation is not 
required to actually use malloc, so depending on that falls 
into "know what you're doing" territory :)


Thanks for the help, but unfortunately it isn't stopping memory 
usage growing in the original app. I will try and build a minimal 
example. In the meantime perhaps someone can suggest how I might 
figure out what is going on. Repeating the same action is giving 
memory usage growth as follows. 1.7GB first time (which now drops 
to about 1GB), then 2.7GB dropping to about 2GB and so on.


Re: Garbage collection

2020-06-27 Thread James Gray via Digitalmars-d-learn

On Saturday, 27 June 2020 at 12:53:01 UTC, James Gray wrote:
On Saturday, 27 June 2020 at 12:07:19 UTC, Stanislav Blinov 
wrote:

On Saturday, 27 June 2020 at 11:35:12 UTC, Arafel wrote:


[...]


That's a good observation. Although a GC implementation is not 
required to actually use malloc, so depending on that falls 
into "know what you're doing" territory :)


Thanks for the help, but unfortunately it isn't stopping memory 
usage growing in the original app. I will try and build a 
minimal example. In the meantime perhaps someone can suggest 
how I might figure out what is going on. Repeating the same 
action is giving memory usage growth as follows. 1.7GB first 
time (which now drops to about 1GB), then 2.7GB dropping to 
about 2GB and so on.


Which eventually results in mac os running out of memory.


Re: Garbage collection

2020-06-27 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 27 June 2020 at 11:35:12 UTC, Arafel wrote:

If you are using linux, have in mind that the memory is often 
not returned to the OS even after a (libc) free.


That's a good observation. Although a GC implementation is not 
required to actually use malloc, so depending on that falls into 
"know what you're doing" territory :)


Re: Garbage collection

2020-06-27 Thread Arafel via Digitalmars-d-learn

On 27/6/20 13:21, Stanislav Blinov wrote:


I would think collect + minimize should do the trick. Just keep in mind 
that that's grossly inefficient.


If you are using linux, have in mind that the memory is often not 
returned to the OS even after a (libc) free. If you check with tools 
like `top`, it'll still show as assigned to the process.


What I had to do (both in D and in C/C++) was to call malloc_trim [1] 
manually to have the memory actually sent back to the OS.


[1]: https://man7.org/linux/man-pages/man3/malloc_trim.3.html


Re: Garbage collection

2020-06-27 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 27 June 2020 at 11:11:38 UTC, James Gray wrote:


I am measuring the memory usage using top from the command line.
GC.minimize() does seem to stop the leak.


That is not a memory leak. That's the allocator keeping pages for 
itself to not have to go to the kernel every time you allocate.


But it doesn't explain why the program isn't releasing 
essentially all the memory between calls to f (it using around 
2GB ram all the time).


Allocators usually don't do that. They keep (at least some) 
memory mapped to make allocations more efficient.



Is there a way of achieving that?


I would think collect + minimize should do the trick. Just keep 
in mind that that's grossly inefficient.


Re: Garbage collection

2020-06-27 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 27 June 2020 at 11:11:38 UTC, James Gray wrote:



I am measuring the memory usage using top from the command line.
GC.minimize() does seem to stop the leak. But it doesn't 
explain why
the program isn't releasing essentially all the memory between 
calls
to f (it using around 2GB ram all the time). Is there a way of 
achieving that?


It's not a leak. The GC allocates memory as it needs it and holds 
on to it. When something is collected, the GC can reuse then 
released memory when it needs it.


Re: Garbage collection

2020-06-27 Thread James Gray via Digitalmars-d-learn

On Saturday, 27 June 2020 at 11:00:58 UTC, Stanislav Blinov wrote:

On Saturday, 27 June 2020 at 10:08:15 UTC, James Gray wrote:

I find that the memory usage grows to about 1.5GB and never 
decreases. Is there something I am not understanding?


How are you measuring that? GC.collect() does not necessarily 
release the pages to the OS. For that, there's the 
GC.minimize().


I am measuring the memory usage using top from the command line.
GC.minimize() does seem to stop the leak. But it doesn't explain 
why
the program isn't releasing essentially all the memory between 
calls
to f (it using around 2GB ram all the time). Is there a way of 
achieving that?


Re: Garbage collection

2020-06-27 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 27 June 2020 at 10:08:15 UTC, James Gray wrote:

I find that the memory usage grows to about 1.5GB and never 
decreases. Is there something I am not understanding?


How are you measuring that? GC.collect() does not necessarily 
release the pages to the OS. For that, there's the GC.minimize().


Re: Garbage collection

2020-06-27 Thread James Gray via Digitalmars-d-learn

On Saturday, 27 June 2020 at 10:08:15 UTC, James Gray wrote:
I am writing a web application using vibe.d (not sure whether 
that is relevant or not), and have run into a memory leak. I 
wrote the following code to try and replicate the problem.


[...]


I now compiled the same code above with ldc2 and it is leaking.
Any suggestions?



Garbage collection

2020-06-27 Thread James Gray via Digitalmars-d-learn
I am writing a web application using vibe.d (not sure whether 
that is relevant or not), and have run into a memory leak. I 
wrote the following code to try and replicate the problem.


import std.algorithm;
import std.range;
import std.format;
import std.stdio;
import core.thread;
import core.memory;

auto f(R)(R r) {
 return format("%s", r);
}

void main()
{
 while(true)
 {
  writeln("Starting");
  {
   auto str = f(iota(1).map!(x=>x+1));
  }
  writeln("Done");
  GC.collect();
  Thread.sleep( dur!("msecs")( 3 ) );
 }
}

 It doesn't replicate the problem but it still doesn't behave as 
I would expect. I would expect the memory usage of this code to 
grow and shrink. However, I find that the memory usage grows to 
about 1.5GB and never decreases. Is there something I am not 
understanding?


Re: How to send ownerTid into a parallel foreach loop?

2020-06-27 Thread adnan338 via Digitalmars-d-learn

On Saturday, 27 June 2020 at 07:31:56 UTC, Kagamin wrote:
std.concurrency is for noninteractive appications, the approach 
with gui timer was the correct one.


Thank you. That works but my progress bar is sometimes getting 
stuck because of a possible data race.
See 
https://forum.dlang.org/post/gacweulvbyorkseti...@forum.dlang.org


Today I discovered Glib Idle so I was trying that out.


Re: How to send ownerTid into a parallel foreach loop?

2020-06-27 Thread Kagamin via Digitalmars-d-learn
std.concurrency is for noninteractive appications, the approach 
with gui timer was the correct one.