Re: Determination of thread status.
std.concurrency is a low-level API. You may be looking for a higher level API: std.parallelism. See Task.done(), https://dlang.org/phobos/std_parallelism.html#.Task.done Bastiaan. Maybe I misunderstood, but the capabilities of the std.parallelism module do not allow to exchange messages with the stream, if so, this does not suit me. Correct me if it is not.
Re: Determination of thread status.
On Tuesday, 25 December 2018 at 17:12:13 UTC, Bastiaan Veelo wrote: std.concurrency is a low-level API. You may be looking for a higher level API: std.parallelism. See Task.done(), https://dlang.org/phobos/std_parallelism.html#.Task.done Bastiaan. Thanks for the answer. I will look at the possibilities of std.parallelism.
Re: Determination of thread status.
On Tuesday, 25 December 2018 at 17:08:00 UTC, Neia Neutuladh wrote: 1. Find the Thread object: Tid threadId = spawn(); auto thread = Thread.getAll.filter!(x => x.id == threadId).front; 2. Check the `isRunning` property. The indirection with spawn() is awkward. Thanks for the answer. I checked. Thread.getAll [x] .id is of type ulong, and spawn is of type Tid, moreover, they do not intersect in value either. But even if the program spawns a single thread, Thread.getAll [x] .isRunning returns true after the function terminates. Perhaps you need to wait some time. You may have to send a message before exiting the function. Just look at the possibilities of std.parallelism. I will gladly try other solutions. I would be grateful for your suggestions.
Handling signals in D
Hello everyone, we are writing a program that synchronizes the OneDrive cloud service with the local computer, and run it as daemon in the background. To ensure proper database shutdown on exit, we need to install signal handlers that react to SIGINT etc. The problem now is that at the same time we use std.net.curl.Curl, and that has some kind of bug in the shutdown routine when it is called during program termination. One always needs to manually call .shutdown, otherwise the program dumps core: ``` (gdb) bt #0 0x in ?? () #1 0x7faf58f7e967 in std.net.curl.HTTP.Impl.~this() () from /usr/lib/x86_64-linux-gnu/libphobos2-ldc-shared.so.82 #2 0x7faf58ebbce9 in _D6object__T7destroyTS3std3net4curl4HTTP4ImplZQBiFKQBeZv () from /usr/lib/x86_64-linux-gnu/libphobos2-ldc-shared.so.82 #3 0x7faf58fce020 in _D3std8typecons__T10RefCountedTSQBe3net4curl4HTTP4ImplVEQCcQCb24RefCountedAutoInitializei1ZQCv6__dtorMFZv () from /usr/lib/x86_64-linux-gnu/libphobos2-ldc-shared.so.82 #4 0x7faf58c8d2ae in rt_finalize2 () from /usr/lib/x86_64-linux-gnu/libdruntime-ldc-shared.so.82 #5 0x7faf58c75af5 in _D2gc4impl12conservativeQw15SmallObjectPool13runFinalizersMFNbxAvZv () from /usr/lib/x86_64-linux-gnu/libdruntime-ldc-shared.so.82 #6 0x7faf58c746cb in _D2gc4impl12conservativeQw3Gcx13runFinalizersMFNbxAvZv () from /usr/lib/x86_64-linux-gnu/libdruntime-ldc-shared.so.82 #7 0x7faf58c7476f in _D2gc4impl12conservativeQw14ConservativeGC__T9runLockedS_DQCeQCeQCcQCnQBs13runFinalizersMFNbxAvZ2goFNbPSQDyQDyQDwQEh3GcxxQBcZvS_DQExQExQEvQFg9otherTimelS_DQFxQFxQFvQGg9numOtherslTQCzTxQDnZQFnMFNbKQDqKxQEeZv () from /usr/lib/x86_64-linux-gnu/libdruntime-ldc-shared.so.82 #8 0x7faf58c75633 in _DThn16_2gc4impl12conservativeQw14ConservativeGC13runFinalizersMFNbxAvZv () from /usr/lib/x86_64-linux-gnu/libdruntime-ldc-shared.so.82 #9 0x7faf58c949bc in _d_dso_registry () from /usr/lib/x86_64-linux-gnu/libdruntime-ldc-shared.so.82 #10 0x561068f9b3b6 in ldc.register_dso () #11 0x7faf59684736 in _dl_fini () at dl-fini.c:138 #12 0x7faf5887de3c in __run_exit_handlers (status=0, listp=0x7faf589ff718 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at exit.c:108 #13 0x7faf5887df6a in __GI_exit (status=) at exit.c:139 #14 ``` Now, unfortunately the call to the shutdown procedure is not possible in `@nogc`, so I am a bit at loss how to deal with all this. The code I am using is: ``` extern(C) @nogc @system void exitHandler(int value) { printf("Ooo got %d\n", value); // workaround for segfault in std.net.curl.Curl.shutdown() on exit oneDrive.http.shutdown(); exit(0); } ``` and in `main` before entering the loop: ``` signal(SIGINT, ); ``` Any suggestion would be very much appreciated. Norbert
Re: cas and interfaces
On Monday, 24 December 2018 at 11:23:32 UTC, Johan Engelen wrote: On Sunday, 23 December 2018 at 14:07:04 UTC, Johannes Loher wrote: [...] The types of the 2nd and 3rd arguments of `cas` do not have to be the same, and aren't in your case. I think what's happening is that you are overwriting `testInterface` with a pointer to a TestClass which is not a valid TestInterface pointer. And then the program does something invalid because, well, you enter UB land. Fixed by: ``` cas(, testInterface, cast(shared(TestInterface)) new shared TestClass).writeln; ``` Note the cast! Whether this is a bug in `cas` or not, I don't know. The `cas` template checks whether the 3rd can be assigned to the 1st argument (`*here = writeThis;`) which indeed compiles _with_ an automatic conversion. But then the implementation of `cas` does not do any automatic conversions (casts to `void*`). Hence the problem you are seeing. -Johan Thanks a lot for the info, that clarifies things a bit. But it still leaves the question, why it works correctly when inheriting from an abstract class instead of implementing an interface... Any idea about why that?
Re: class template conflict
On Tuesday, 25 December 2018 at 18:34:04 UTC, bauss wrote: On Monday, 24 December 2018 at 00:24:05 UTC, Michelle Long wrote: More simple is : do not use the same identifier ;) The whole point is to use the same identifier ;/ I think there is a bigger problem at stake here in terms of software architecture. No, the problem is reasoning from the conclusion...
Re: class template conflict
On Tue, 25 Dec 2018 18:34:04 +, bauss wrote: > I think there is a bigger problem at stake here in terms of software > architecture. > > What's the point needed for them to have the same identifier? A probably abstract base class with only one child class. Normally you have "Foo" and "FooImpl", or "IFoo" and "Foo", but that's ugly. This was the primary example that Michelle Long gave. I'd expect that a fair portion of people people who have used C# encountered this kind of situtaion. Like this sort of thing works in C#: class Foo {} class Foo : Foo {} class Foo : Foo {} You can do this in C# because each of these are *classes*, and some just happen to have type parameters. In D, you'd have one class and two templates, and you can't overload two symbols of different kinds, so you have to write it as: class Foo() {} class Foo(T): Foo!() {} class Foo(T, U): Foo!() {} In Java, for legacy reasons, this pattern is baked into the language; Foo always has another class, Foo, that it implicitly casts to and from. Some people take advantage of that. Most people who do both metaprogramming and OOP in D and have been doing that for a nontrivial amount of time probably encountered this exact same thing in D. I encountered it the first time before D2 was a thing. > Clearly the two classes will have two different functions and should be > named accordingly. They will have different implementations and may have different interfaces. The proposed use case is inheritance, so X!10's public interface will be a superset of X's (and likely identical). To give a slightly less contrived example, let's say you want to have some functions available to a scripting language. (I'm doing something like this in a side project for a CLI spreadsheet program.) Each function has a display name, help text, argument validation, and the function body. If I had done this in an OOP style (and I might end up reworking it to look more like this), I'd have something like: interface Function { string helpText(); string name(); Nullable!Error validateParameters(Val[] parameters); Val execute(Val[] parameters); } And then I'd have a convenience mechanism to produce a conforming class from a function with UDAs: class FunctionImpl(alias fn) : Function { override: string helpText() { return getUDAs!(fn, Help)[0].text; } string name() { return __traits(identifier, fn); } // etc } It would be slightly nicer to just have "Function" everywhere instead of both Function and FunctionImpl. Not enough to justify the complexity of the symbol lookup rules required. Not enough to make `class Foo(T)` mean something different from `template Foo(T) class Foo`. But it *would* be slightly nicer, and it would make things slightly more straightforward for people coming from C#.
Re: DSFML linking fails
On Monday, 24 December 2018 at 10:08:25 UTC, Dmitriy wrote: Hello. I'm using https://github.com/Jebbs/DSFML library [...] Create an issue here: https://github.com/Jebbs/DSFML/issues
Re: class template conflict
On Monday, 24 December 2018 at 00:24:05 UTC, Michelle Long wrote: More simple is : do not use the same identifier ;) The whole point is to use the same identifier ;/ I think there is a bigger problem at stake here in terms of software architecture. What's the point needed for them to have the same identifier? Clearly the two classes will have two different functions and should be named accordingly. Ex. class X { ... } class X(int N) { ... } Could be something like: class X { ... } class XWithArguments { ... } There is absolutely no point of them having same identifiers unless they did the exact same thing and in that case you'd probably just not want this anyway. A solution to this would be something like: interface X { } class XWithoutArguments : X { } class XWithArguments : X { }
Re: Determination of thread status.
On Tuesday, 25 December 2018 at 14:44:43 UTC, Vitaly wrote: Hi all. I can not understand how to track me that the thread has finished work. eg: import std.concurrency; void myThread () { // Do the work } void main () { Tid thread = spawn (& myThread); // It is necessary to check whether the thread has finished its work or is active. } Could you tell me how to do this? std.concurrency is a low-level API. You may be looking for a higher level API: std.parallelism. See Task.done(), https://dlang.org/phobos/std_parallelism.html#.Task.done Bastiaan.
Re: Determination of thread status.
1. Find the Thread object: Tid threadId = spawn(); auto thread = Thread.getAll.filter!(x => x.id == threadId).front; 2. Check the `isRunning` property. The indirection with spawn() is awkward.
Re: class template conflict
On Tue, 25 Dec 2018 16:55:36 +, Neia Neutuladh wrote: And I forgot part of it. Let's say we did the work to make this function: class X {} template X(int N) { // `: X` somehow refers to the X in the outer scope class X : X {} } How do you distinguish between the base class and the derived class in there? You'd have to use typeof(this) and typeof(super) everywhere. And externally, how do you refer to class X and template X separately? If you have a template with an alias parameter and pass X, how do you pass class-X and how do you pass template-X? This is already unpleasant with functions, and there's a way to distinguish them.
Re: class template conflict
On Tue, 25 Dec 2018 13:03:13 +, Michelle Long wrote: > But I am not talking about inside the template being used. The whole > point of doing this is so that one can refer to the base class using the > same name as the derived with a template parameter to make a composite > structure. The following are entirely equivalent: class X(int N) : X {} template X(int N) { class X : X {} } You want to be able to do, essentially: class X {} template X(int N) { // `: X` somehow refers to the X in the outer scope class X : X {} } And sure, this specific case obviously doesn't work if the `: X` refers to the template or the class inside the template. But the symbol lookup rules aren't "try everything and see what sticks". You look up the nearest symbol and then you just use that. It would be like arguing that, in the following example, the compiler should know that ints aren't callable and should call the function: void foo() { writeln("merr critmis"); } void main() { int foo = 10; foo(); } Which isn't obviously wrong, but it does make things harder to understand.
Re: Qualified class opEquals()
On Tuesday, 25 December 2018 at 14:27:39 UTC, Per Nordlöw wrote: This is a severe limitation. Are there any plans on fixing this or do I have to wait for Andrei's proposed ProtoObject? Ignore opEquals and use your own interface.
Determination of thread status.
Hi all. I can not understand how to track me that the thread has finished work. eg: import std.concurrency; void myThread () { // Do the work } void main () { Tid thread = spawn (& myThread); // It is necessary to check whether the thread has finished its work or is active. } Could you tell me how to do this?
Re: Qualified class opEquals()
On Tuesday, 25 December 2018 at 00:32:55 UTC, Paul Backus wrote: No, because equality comparison between classes lowers to `object.opEquals` [1], which takes both parameters as `Object`. This is a severe limitation. Are there any plans on fixing this or do I have to wait for Andrei's proposed ProtoObject?
Re: class template conflict
On Monday, 24 December 2018 at 22:55:55 UTC, Daniel Kozak wrote: ne 23. 12. 2018 13:10 odesílatel Michelle Long via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> napsal: class X { } class X(int N) : X { } Is there any real reason we can't do this? Actually yes. It would break almost all of my code. How would it break your code? In D you can do thing like this: class X(int N) { X something; // it is same as X!N something; } So I do not need to write X!N everywhere inside X class template But I am not talking about inside the template being used. The whole point of doing this is so that one can refer to the base class using the same name as the derived with a template parameter to make a composite structure. X!N should be totally different than X. The fact that you can use X inside a class to refer to X!N is a hack... and in any case should not effect what I'm talking about because it is only used in the inherited part.. which it would be circular to use it as it is: class X(int N) : X { } creates circular inheritance. so for the inherited part it should never be used and you never use it in your code like that... so it won't break anything. Also, as long as there is no other symbol with that name it won't break anything. Suppose this did work: class X; class X(int N) : X // (Here X refers to the base class above { // Using X can still be X!N since we can just alias the original X away. } class X; alias XX = X; class X(int N) : X { X x; // X!N x; XX xx; // X = x; } So it would not break anything. It really has nothing to do with what one does inside a template but how it looks to the outside.