update wake timer

This commit is contained in:
Luke Pulverenti 2016-01-21 12:45:42 -05:00
parent 06f8047ee6
commit a10347a455
4 changed files with 71 additions and 15 deletions

View File

@ -1954,6 +1954,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false); await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false);
_lastRecordingRefreshTime = DateTime.MinValue; _lastRecordingRefreshTime = DateTime.MinValue;
_logger.Info("New recording scheduled");
} }
public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken)

View File

@ -218,7 +218,7 @@ namespace MediaBrowser.ServerApplication
var fileSystem = new WindowsFileSystem(new PatternsLogger(logManager.GetLogger("FileSystem"))); var fileSystem = new WindowsFileSystem(new PatternsLogger(logManager.GetLogger("FileSystem")));
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
var nativeApp = new WindowsApp(fileSystem) var nativeApp = new WindowsApp(fileSystem, _logger)
{ {
IsRunningAsService = runService IsRunningAsService = runService
}; };

View File

@ -13,10 +13,12 @@ namespace MediaBrowser.ServerApplication.Native
public class WindowsApp : INativeApp public class WindowsApp : INativeApp
{ {
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly ILogger _logger;
public WindowsApp(IFileSystem fileSystem) public WindowsApp(IFileSystem fileSystem, ILogger logger)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;
_logger = logger;
} }
public List<Assembly> GetAssembliesWithParts() public List<Assembly> GetAssembliesWithParts()
@ -121,7 +123,7 @@ namespace MediaBrowser.ServerApplication.Native
public IPowerManagement GetPowerManagement() public IPowerManagement GetPowerManagement()
{ {
return new WindowsPowerManagement(); return new WindowsPowerManagement(_logger);
} }
} }
} }

View File

@ -3,6 +3,7 @@ using System.ComponentModel;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using MediaBrowser.Controller.Power; using MediaBrowser.Controller.Power;
using MediaBrowser.Model.Logging;
using Microsoft.Win32.SafeHandles; using Microsoft.Win32.SafeHandles;
namespace MediaBrowser.ServerApplication.Native namespace MediaBrowser.ServerApplication.Native
@ -10,30 +11,82 @@ namespace MediaBrowser.ServerApplication.Native
public class WindowsPowerManagement : IPowerManagement public class WindowsPowerManagement : IPowerManagement
{ {
[DllImport("kernel32.dll")] [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)] [DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [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) 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; using (EventWaitHandle wh = new EventWaitHandle(false,
wh.WaitOne(); EventResetMode.AutoReset))
{
wh.SafeWaitHandle = handle;
wh.WaitOne();
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
} }
} }
else }
{ catch (Exception ex)
throw new Win32Exception(Marshal.GetLastWin32Error()); {
} _logger.ErrorException("Error scheduling wake timer", ex);
} }
} }
} }