Opened 10 months ago

Last modified 4 weeks ago

#3011 new feature-request

Listen to WM_ENDSESSION on Windows

Reported by: joeyvh Owned by:
Priority: minor Milestone: 1.3.16
Component: GTK UI Version: 1.3.14
Keywords: Cc:


Right now, on Windows, when a torrent is downloading and Windows' session ends (Either via shutdown or log off) Deluge is forcedly shutdown and the torrent goes into error state. It needs to force recheck the next time Deluge is started.

Suggest listening to the WM_ENDSESSION message so that Deluge can gracefully exit and not push incomplete torrents into error state.

Attachments (1)

deluge.log (50.5 KB) - added by joeyvh 10 months ago.

Download all attachments as: .zip

Change History (10)

comment:1 Changed 10 months ago by Cas

Could you enable debug logging and look for ctrl_type: entry as it might be missing an event.

Changed 10 months ago by joeyvh

comment:2 Changed 10 months ago by joeyvh

Attached deluge.log

Test case: Set log level to "Debug". I had already added a torrent to test. After opening and leaving open for a while, I shut down the PC with deluge still running.

There seems to be no mention of "ctrl_type" at all anywhere in the log file.

comment:3 Changed 10 months ago by Cas

Hmm ok, thanks. I shall have to look into how to implement WM_ENDSESSION in Python.

You could see if using deluge-debug.exe or switching to Thinclient mode works in the meantime.

comment:4 Changed 10 months ago by joeyvh

Alright, thank you. For now I'll simply be extra careful to quit deluge before shutting down the PC when a download is running.

If I can do anything to help test / debug, please let me know.

comment:5 Changed 10 months ago by Cas

  • Milestone changed from needs verified to 1.3.15

comment:6 Changed 8 months ago by Cas

  • Component changed from Unknown to GTK UI
  • Version changed from other (please specify) to 1.3.14

Collated information for ongoing dev...

Code to test pid handling messages:

from win32con import WM_QUERYENDSESSION
from win32gui import EnumWindows, GetClassName, IsWindowEnabled, IsWindowVisible
from win32process import GetWindowThreadProcessId

def get_hwnds_for_pid(pid):
    def enumwins_cb(hwnd, hwnds):
        if IsWindowVisible(hwnd) and IsWindowEnabled(hwnd):
            # print(GetClassName(hwnd), GetWindowThreadProcessId(hwnd)[1])
            if pid == GetWindowThreadProcessId(hwnd)[1]:
        return True

    hwnds = []
    EnumWindows(enumwins_cb, hwnds)
    return hwnds
def shutdown_pid(pid):
    win32api.PostMessage(get_hwnds_for_pid(pid)[0], WM_QUERYENDSESSION)

Last edited 8 months ago by Cas (previous) (diff)

comment:7 Changed 8 months ago by Cas

  • Milestone changed from 1.3.15 to 1.3.16

Ticket retargeted after milestone closed

comment:8 Changed 4 weeks ago by DjLegolas

As I wrote in the pull request, I wrote a handler for this in my fork.

On WM_QUERYENDSESSION message, Deluge will register itself as a Shutdown-Blocker. Next, when receiving WM_ENDSESSION message, Deluge should have 30 seconds to save all the data - depending on whether critical shutdown or not.

But the lack of a proper tool for testing this makes me feel like the is something wrong with my work.

comment:9 Changed 4 weeks ago by Cas

Have you done any testing of your proposed changes? It's been a while since I touched this code so can't remember exactly where I was but testing was a challenge. I only use Windows on virtualbox VMs which makes it a bit easier for actual OS restarts.

I think it is possible to block shutdown entirely if Deluge doesn't return True at some point.

Also you only really need to do this shutdown blocking in classic/standalone mode and there is a section of unneeded duplicate code from what I can see. In thinclient mode the daemon would get it own shutdown message from the OS and deal with it as it does currently.

Note: See TracTickets for help on using tickets.