Как изящно выйти из D-программы, когда ctrl + c происходит? - PullRequest
0 голосов
/ 07 декабря 2018

Я хотел бы корректно завершить работу приложения vibe.d, остановив eventloop.

import vibe.vibe;
import core.sys.posix.signal;

void main()
{
  enum SIGINT = 2;
  signal(SIGINT, &stopapp);

  auto settings = new HTTPServerSettings;
  settings.port = 8080;
  settings.bindAddresses = ["::1", "127.0.0.1"];
  listenHTTP(settings, &hello);

  logInfo("Please open http://127.0.0.1:8080/ in your browser.");
  runApplication();

}

void hello(HTTPServerRequest req, HTTPServerResponse res)
{
  res.writeBody("Hello, World!");
}

void stopapp(int value){
  logInfo("Stopping app...");
  exitEventLoop();
}

К сожалению, это не работает:

source/app.d(7,9): Error: function core.stdc.signal.signal(int sig, extern (C) void function(int) nothrow @nogc @system func) is not callable using argument types (int, void function(int value))
source/app.d(7,9):        cannot pass argument & stopapp of type void function(int value) to parameter extern (C) void function(int) nothrow @nogc @system func
dmd failed with exit code 1.

Существует ли простая библиотека, котораяэто делает?

1 Ответ

0 голосов
/ 07 декабря 2018

signal - это функция C.Чтобы функция C вызывала функцию D, функцию D следует пометить как extern(C) signalHandler().

import  std.stdio;

extern(C) void signal(int sig, void function(int) );

// Our handler, callable by C
extern(C) void handle(int sig) {
    writeln("Signal:",sig);
}

void main()
{
    enum SIGINT = 2; // OS-specific

    signal(SIGINT,&handle);
    writeln("Hello!");
    readln();
    writeln("End!");
}

Как и в вашем примере с vibe.d, vibe.d обрабатывает SIGINT самостоятельно.Это должно работать:

import vibe.vibe;

void main()
{
    auto settings = new HTTPServerSettings;
    settings.port = 8080;
    settings.bindAddresses = ["::1", "127.0.0.1"];
    listenHTTP(settings, &hello);

    logInfo("Please open http://127.0.0.1:8080/ in your browser.");
    runApplication();
}

void hello(HTTPServerRequest req, HTTPServerResponse res)
{
    res.writeBody("Hello, World!");
}

Запустите это и нажмите Cc.

09:21:59 ~/code/d/stackoverflow/q1
$ ./q1
[main(----) INF] Listening for requests on http://[::1]:8080/
[main(----) INF] Listening for requests on http://127.0.0.1:8080/
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.
^C[main(----) INF] Received signal 2. Shutting down.
Warning (thread: main): leaking eventcore driver because there are still active handles
FD 6 (streamListen)
FD 7 (streamListen)
Warning (thread: main): leaking eventcore driver because there are still active handles
FD 6 (streamListen)
FD 7 (streamListen)
09:22:04 ~/code/d/stackoverflow/q1
$
...