-
Notifications
You must be signed in to change notification settings - Fork 16.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Multiple instances of ss_privoxy (#665)
* Use job object to manage polipo service's external processes. Signed-off-by: noisyfox <timemanager.rick@gmail.com> * Only kill those ss_privoxy.exe created by this ss instance. Signed-off-by: noisyfox <timemanager.rick@gmail.com> * Update README Signed-off-by: noisyfox <timemanager.rick@gmail.com>
- Loading branch information
1 parent
e304872
commit a1eef6e
Showing
6 changed files
with
259 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.Runtime.InteropServices; | ||
using Shadowsocks.Controller; | ||
|
||
namespace Shadowsocks.Util.ProcessManagement | ||
{ | ||
/* | ||
* See: | ||
* http://stackoverflow.com/questions/6266820/working-example-of-createjobobject-setinformationjobobject-pinvoke-in-net | ||
*/ | ||
public class Job : IDisposable | ||
{ | ||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] | ||
static extern IntPtr CreateJobObject(IntPtr a, string lpName); | ||
|
||
[DllImport("kernel32.dll")] | ||
static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength); | ||
|
||
[DllImport("kernel32.dll", SetLastError = true)] | ||
static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process); | ||
|
||
[DllImport("kernel32.dll", SetLastError = true)] | ||
[return: MarshalAs(UnmanagedType.Bool)] | ||
static extern bool CloseHandle(IntPtr hObject); | ||
|
||
private IntPtr handle; | ||
private bool disposed; | ||
|
||
public Job() | ||
{ | ||
handle = CreateJobObject(IntPtr.Zero, null); | ||
|
||
var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION | ||
{ | ||
LimitFlags = 0x2000 | ||
}; | ||
|
||
var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION | ||
{ | ||
BasicLimitInformation = info | ||
}; | ||
|
||
int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); | ||
IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length); | ||
Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false); | ||
|
||
if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length)) | ||
throw new Exception(string.Format("Unable to set information. Error: {0}", Marshal.GetLastWin32Error())); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
private void Dispose(bool disposing) | ||
{ | ||
if (disposed) | ||
return; | ||
|
||
if (disposing) { } | ||
|
||
Close(); | ||
disposed = true; | ||
} | ||
|
||
public void Close() | ||
{ | ||
CloseHandle(handle); | ||
handle = IntPtr.Zero; | ||
} | ||
|
||
public bool AddProcess(IntPtr processHandle) | ||
{ | ||
var succ = AssignProcessToJobObject(handle, processHandle); | ||
|
||
if (!succ) | ||
{ | ||
var err = Marshal.GetLastWin32Error(); | ||
Logging.Error("Failed to call AssignProcessToJobObject! GetLastError=" + err); | ||
} | ||
|
||
return succ; | ||
} | ||
|
||
public bool AddProcess(int processId) | ||
{ | ||
return AddProcess(Process.GetProcessById(processId).Handle); | ||
} | ||
|
||
} | ||
|
||
#region Helper classes | ||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
struct IO_COUNTERS | ||
{ | ||
public UInt64 ReadOperationCount; | ||
public UInt64 WriteOperationCount; | ||
public UInt64 OtherOperationCount; | ||
public UInt64 ReadTransferCount; | ||
public UInt64 WriteTransferCount; | ||
public UInt64 OtherTransferCount; | ||
} | ||
|
||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
struct JOBOBJECT_BASIC_LIMIT_INFORMATION | ||
{ | ||
public Int64 PerProcessUserTimeLimit; | ||
public Int64 PerJobUserTimeLimit; | ||
public UInt32 LimitFlags; | ||
public UIntPtr MinimumWorkingSetSize; | ||
public UIntPtr MaximumWorkingSetSize; | ||
public UInt32 ActiveProcessLimit; | ||
public UIntPtr Affinity; | ||
public UInt32 PriorityClass; | ||
public UInt32 SchedulingClass; | ||
} | ||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
public struct SECURITY_ATTRIBUTES | ||
{ | ||
public UInt32 nLength; | ||
public IntPtr lpSecurityDescriptor; | ||
public Int32 bInheritHandle; | ||
} | ||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION | ||
{ | ||
public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; | ||
public IO_COUNTERS IoInfo; | ||
public UIntPtr ProcessMemoryLimit; | ||
public UIntPtr JobMemoryLimit; | ||
public UIntPtr PeakProcessMemoryUsed; | ||
public UIntPtr PeakJobMemoryUsed; | ||
} | ||
|
||
public enum JobObjectInfoType | ||
{ | ||
AssociateCompletionPortInformation = 7, | ||
BasicLimitInformation = 2, | ||
BasicUIRestrictions = 4, | ||
EndOfJobTimeInformation = 6, | ||
ExtendedLimitInformation = 9, | ||
SecurityLimitInformation = 5, | ||
GroupInformation = 11 | ||
} | ||
|
||
#endregion | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System.Diagnostics; | ||
using System.Management; | ||
using System.Text; | ||
|
||
namespace Shadowsocks.Util.ProcessManagement | ||
{ | ||
static class ThreadUtil | ||
{ | ||
|
||
/* | ||
* See: | ||
* http://stackoverflow.com/questions/2633628/can-i-get-command-line-arguments-of-other-processes-from-net-c | ||
*/ | ||
public static string GetCommandLine(this Process process) | ||
{ | ||
var commandLine = new StringBuilder(process.MainModule.FileName); | ||
|
||
commandLine.Append(" "); | ||
using (var searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id)) | ||
{ | ||
foreach (var @object in searcher.Get()) | ||
{ | ||
commandLine.Append(@object["CommandLine"]); | ||
commandLine.Append(" "); | ||
} | ||
} | ||
|
||
return commandLine.ToString(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters