From a10347a455fbc27284caa8a42c5e77cda9683eab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 12:45:42 -0500 Subject: [PATCH] update wake timer --- .../LiveTv/LiveTvManager.cs | 1 + MediaBrowser.ServerApplication/MainStartup.cs | 2 +- .../Native/WindowsApp.cs | 6 +- .../Native/WindowsPowerManagement.cs | 77 ++++++++++++++++--- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index e09e06bd4b..8bf1d27b8b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1954,6 +1954,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; + _logger.Info("New recording scheduled"); } public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 62cdbd05f4..cf174c2d3b 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -218,7 +218,7 @@ namespace MediaBrowser.ServerApplication var fileSystem = new WindowsFileSystem(new PatternsLogger(logManager.GetLogger("FileSystem"))); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); - var nativeApp = new WindowsApp(fileSystem) + var nativeApp = new WindowsApp(fileSystem, _logger) { IsRunningAsService = runService }; diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 9ef9c7d501..fe2fe6de6c 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -13,10 +13,12 @@ namespace MediaBrowser.ServerApplication.Native public class WindowsApp : INativeApp { private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; - public WindowsApp(IFileSystem fileSystem) + public WindowsApp(IFileSystem fileSystem, ILogger logger) { _fileSystem = fileSystem; + _logger = logger; } public List GetAssembliesWithParts() @@ -121,7 +123,7 @@ namespace MediaBrowser.ServerApplication.Native public IPowerManagement GetPowerManagement() { - return new WindowsPowerManagement(); + return new WindowsPowerManagement(_logger); } } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs index 6bd78553b6..3b05febafe 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.Runtime.InteropServices; using System.Threading; using MediaBrowser.Controller.Power; +using MediaBrowser.Model.Logging; using Microsoft.Win32.SafeHandles; namespace MediaBrowser.ServerApplication.Native @@ -10,30 +11,82 @@ namespace MediaBrowser.ServerApplication.Native public class WindowsPowerManagement : IPowerManagement { [DllImport("kernel32.dll")] - public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName); + public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, + bool bManualReset, + string lpTimerName); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In] ref long pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume); + public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, + [In] ref long pDueTime, + int lPeriod, + IntPtr pfnCompletionRoutine, + IntPtr lpArgToCompletionRoutine, + bool fResume); + + private BackgroundWorker _bgWorker; + private readonly ILogger _logger; + private readonly object _initLock = new object(); + + public WindowsPowerManagement(ILogger logger) + { + _logger = logger; + } public void ScheduleWake(DateTime utcTime) { - long duetime = utcTime.ToFileTime(); + Initialize(); + _bgWorker.RunWorkerAsync(utcTime.ToFileTime()); + } - using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, true, "MyWaitabletimer")) + private void Initialize() + { + lock (_initLock) { - if (SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero, IntPtr.Zero, true)) + if (_bgWorker == null) { - using (EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset)) + _bgWorker = new BackgroundWorker(); + + _bgWorker.DoWork += bgWorker_DoWork; + _bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted; + } + } + } + + void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + //if (Woken != null) + //{ + // Woken(this, new EventArgs()); + //} + } + + private void bgWorker_DoWork(object sender, DoWorkEventArgs e) + { + try + { + long waketime = (long)e.Argument; + + using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, true, GetType().Assembly.GetName().Name + "Timer")) + { + if (SetWaitableTimer(handle, ref waketime, 0, IntPtr.Zero, IntPtr.Zero, true)) { - wh.SafeWaitHandle = handle; - wh.WaitOne(); + using (EventWaitHandle wh = new EventWaitHandle(false, + EventResetMode.AutoReset)) + { + wh.SafeWaitHandle = handle; + wh.WaitOne(); + } + } + else + { + throw new Win32Exception(Marshal.GetLastWin32Error()); } } - else - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } + } + catch (Exception ex) + { + _logger.ErrorException("Error scheduling wake timer", ex); } } }