diff --git a/implementations/main.cpp b/implementations/main.cpp index 6577884..b06423a 100644 --- a/implementations/main.cpp +++ b/implementations/main.cpp @@ -1330,7 +1330,7 @@ struct Job { // Everything the worker sends back to the main thread. Delivered by g_idle_add // so the D-Bus emission happens on the thread that owns the connection. struct Event { - enum class Kind { Ready, StartFailed, ClaimDone, EnrollStatus, VerifyStatus, OpFinished } kind; + enum class Kind { Ready, StartFailed, ClaimDone, EnrollStatus, VerifyStatus } kind; bool ok = false; bool done = false; std::string status; @@ -1430,7 +1430,6 @@ private: else ev->status = "enroll-failed"; if (!o.why.empty()) std::println("enrolment: {}", o.why); PostEvent(std::move(ev)); - PostEvent(std::make_unique(Event{ .kind = Event::Kind::OpFinished })); break; } case Job::Kind::Verify: { @@ -1443,7 +1442,6 @@ private: else if (o.matched) ev->status = "verify-match"; else ev->status = "verify-no-match"; PostEvent(std::move(ev)); - PostEvent(std::make_unique(Event{ .kind = Event::Kind::OpFinished })); break; } } @@ -1646,10 +1644,6 @@ void PostEvent(std::unique_ptr ev) { if (ev->done && ev->status == "verify-match") std::println("verified fid {} for uid {}", ev->fid, g_claim.uid); break; - case Event::Kind::OpFinished: - g_claim.op = Op::None; - g_claim.finger.clear(); - break; } return G_SOURCE_REMOVE; }, ev.release()); @@ -1825,7 +1819,14 @@ void HandleDevice(GDBusMethodInvocation* inv, std::string_view method, GVariant* ReturnError(inv, "NoActionInProgress", "no such operation in progress"); return; } + // The operation is over when the CLIENT says so. A `done` status only + // means no more status is coming; fprintd's clients call Stop after + // it, and clearing the op ourselves on `done` made every one of them + // fail with NoActionInProgress. Cancelling a loop that already ended + // is harmless. g_worker->CancelOp(); + g_claim.op = Op::None; + g_claim.finger.clear(); g_dbus_method_invocation_return_value(inv, nullptr); return; }