diff options
author | Melanie | 2009-10-22 07:12:10 +0100 |
---|---|---|
committer | Melanie | 2009-10-22 07:12:10 +0100 |
commit | c4969d47d9bbc22b37054451cd31451ca8d8c78a (patch) | |
tree | 788e3b034254bcf068ca950ee97a78b6aa07b386 /OpenSim/Framework | |
parent | Merge branch 'master' into vehicles (diff) | |
parent | Remove the "mel_t" from version string (diff) | |
download | opensim-SC-c4969d47d9bbc22b37054451cd31451ca8d8c78a.zip opensim-SC-c4969d47d9bbc22b37054451cd31451ca8d8c78a.tar.gz opensim-SC-c4969d47d9bbc22b37054451cd31451ca8d8c78a.tar.bz2 opensim-SC-c4969d47d9bbc22b37054451cd31451ca8d8c78a.tar.xz |
Merge branch 'master' into vehicles
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Communications/RestClient.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/IClientAPI.cs | 257 | ||||
-rw-r--r-- | OpenSim/Framework/Location.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/MainServer.cs | 19 | ||||
-rwxr-xr-x | OpenSim/Framework/MinHeap.cs | 375 | ||||
-rw-r--r-- | OpenSim/Framework/Parallel.cs | 14 | ||||
-rw-r--r-- | OpenSim/Framework/RegionInfo.cs | 7 | ||||
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/ThrottleOutPacketType.cs | 12 | ||||
-rw-r--r-- | OpenSim/Framework/Util.cs | 93 |
10 files changed, 738 insertions, 45 deletions
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs index a74169e..97b3b60 100644 --- a/OpenSim/Framework/Communications/RestClient.cs +++ b/OpenSim/Framework/Communications/RestClient.cs | |||
@@ -403,7 +403,7 @@ namespace OpenSim.Framework.Communications | |||
403 | /// In case, we are invoked asynchroneously this object will keep track of the state | 403 | /// In case, we are invoked asynchroneously this object will keep track of the state |
404 | /// </summary> | 404 | /// </summary> |
405 | AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state); | 405 | AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state); |
406 | ThreadPool.QueueUserWorkItem(RequestHelper, ar); | 406 | Util.FireAndForget(RequestHelper, ar); |
407 | return ar; | 407 | return ar; |
408 | } | 408 | } |
409 | 409 | ||
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 9fd043c..d304345 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -448,6 +448,10 @@ namespace OpenSim.Framework | |||
448 | public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages); | 448 | public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages); |
449 | public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); | 449 | public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); |
450 | 450 | ||
451 | public delegate void AgentFOV(IClientAPI client, float verticalAngle); | ||
452 | |||
453 | public delegate double UpdatePriorityHandler(UpdatePriorityData data); | ||
454 | |||
451 | #endregion | 455 | #endregion |
452 | 456 | ||
453 | public struct DirPlacesReplyData | 457 | public struct DirPlacesReplyData |
@@ -517,6 +521,232 @@ namespace OpenSim.Framework | |||
517 | public float dwell; | 521 | public float dwell; |
518 | } | 522 | } |
519 | 523 | ||
524 | public struct SendAvatarData | ||
525 | { | ||
526 | public readonly ulong RegionHandle; | ||
527 | public readonly string FirstName; | ||
528 | public readonly string LastName; | ||
529 | public readonly string GroupTitle; | ||
530 | public readonly UUID AvatarID; | ||
531 | public readonly uint AvatarLocalID; | ||
532 | public readonly Vector3 Position; | ||
533 | public readonly byte[] TextureEntry; | ||
534 | public readonly uint ParentID; | ||
535 | public readonly Quaternion Rotation; | ||
536 | |||
537 | public SendAvatarData(ulong regionHandle, string firstName, string lastName, string groupTitle, UUID avatarID, | ||
538 | uint avatarLocalID, Vector3 position, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
539 | { | ||
540 | RegionHandle = regionHandle; | ||
541 | FirstName = firstName; | ||
542 | LastName = lastName; | ||
543 | GroupTitle = groupTitle; | ||
544 | AvatarID = avatarID; | ||
545 | AvatarLocalID = avatarLocalID; | ||
546 | Position = position; | ||
547 | TextureEntry = textureEntry; | ||
548 | ParentID = parentID; | ||
549 | Rotation = rotation; | ||
550 | } | ||
551 | } | ||
552 | |||
553 | public struct SendAvatarTerseData | ||
554 | { | ||
555 | public readonly ulong RegionHandle; | ||
556 | public readonly ushort TimeDilation; | ||
557 | public readonly uint LocalID; | ||
558 | public readonly Vector3 Position; | ||
559 | public readonly Vector3 Velocity; | ||
560 | public readonly Vector3 Acceleration; | ||
561 | public readonly Quaternion Rotation; | ||
562 | public readonly Vector4 CollisionPlane; | ||
563 | public readonly UUID AgentID; | ||
564 | public readonly byte[] TextureEntry; | ||
565 | public readonly double Priority; | ||
566 | |||
567 | public SendAvatarTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, | ||
568 | Vector3 acceleration, Quaternion rotation, Vector4 collisionPlane, UUID agentid, byte[] textureEntry, double priority) | ||
569 | { | ||
570 | RegionHandle = regionHandle; | ||
571 | TimeDilation = timeDilation; | ||
572 | LocalID = localID; | ||
573 | Position = position; | ||
574 | Velocity = velocity; | ||
575 | Acceleration = acceleration; | ||
576 | Rotation = rotation; | ||
577 | CollisionPlane = collisionPlane; | ||
578 | AgentID = agentid; | ||
579 | TextureEntry = textureEntry; | ||
580 | Priority = priority; | ||
581 | } | ||
582 | } | ||
583 | |||
584 | public struct SendPrimitiveTerseData | ||
585 | { | ||
586 | public readonly ulong RegionHandle; | ||
587 | public readonly ushort TimeDilation; | ||
588 | public readonly uint LocalID; | ||
589 | public readonly Vector3 Position; | ||
590 | public readonly Quaternion Rotation; | ||
591 | public readonly Vector3 Velocity; | ||
592 | public readonly Vector3 Acceleration; | ||
593 | public readonly Vector3 AngularVelocity; | ||
594 | public readonly byte State; | ||
595 | public readonly UUID AssetID; | ||
596 | public readonly UUID OwnerID; | ||
597 | public readonly int AttachPoint; | ||
598 | public readonly byte[] TextureEntry; | ||
599 | public readonly double Priority; | ||
600 | |||
601 | public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, | ||
602 | Quaternion rotation, Vector3 velocity, Vector3 acceleration, Vector3 rotationalvelocity, byte state, | ||
603 | UUID assetID, UUID ownerID, int attachPoint, byte[] textureEntry, double priority) | ||
604 | { | ||
605 | RegionHandle = regionHandle; | ||
606 | TimeDilation = timeDilation; | ||
607 | LocalID = localID; | ||
608 | Position = position; | ||
609 | Rotation = rotation; | ||
610 | Velocity = velocity; | ||
611 | Acceleration = acceleration; | ||
612 | AngularVelocity = rotationalvelocity; | ||
613 | State = state; | ||
614 | AssetID = assetID; | ||
615 | OwnerID = ownerID; | ||
616 | AttachPoint = attachPoint; | ||
617 | TextureEntry = textureEntry; | ||
618 | Priority = priority; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | public struct SendPrimitiveData | ||
623 | { | ||
624 | private ulong m_regionHandle; | ||
625 | private ushort m_timeDilation; | ||
626 | private uint m_localID; | ||
627 | private PrimitiveBaseShape m_primShape; | ||
628 | private Vector3 m_pos; | ||
629 | private Vector3 m_vel; | ||
630 | private Vector3 m_acc; | ||
631 | private Quaternion m_rotation; | ||
632 | private Vector3 m_rvel; | ||
633 | private PrimFlags m_flags; | ||
634 | private UUID m_objectID; | ||
635 | private UUID m_ownerID; | ||
636 | private string m_text; | ||
637 | private byte[] m_color; | ||
638 | private uint m_parentID; | ||
639 | private byte[] m_particleSystem; | ||
640 | private byte m_clickAction; | ||
641 | private byte m_material; | ||
642 | private byte[] m_textureanim; | ||
643 | private bool m_attachment; | ||
644 | private uint m_AttachPoint; | ||
645 | private UUID m_AssetId; | ||
646 | private UUID m_SoundId; | ||
647 | private double m_SoundVolume; | ||
648 | private byte m_SoundFlags; | ||
649 | private double m_SoundRadius; | ||
650 | private double m_priority; | ||
651 | |||
652 | public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
653 | Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||
654 | uint flags, UUID objectID, UUID ownerID, string text, byte[] color, | ||
655 | uint parentID, byte[] particleSystem, byte clickAction, byte material, double priority) : | ||
656 | this(regionHandle, timeDilation, localID, primShape, pos, vel, acc, rotation, rvel, flags, objectID, | ||
657 | ownerID, text, color, parentID, particleSystem, clickAction, material, new byte[0], false, 0, UUID.Zero, | ||
658 | UUID.Zero, 0, 0, 0, priority) { } | ||
659 | |||
660 | public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
661 | Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||
662 | uint flags, | ||
663 | UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, | ||
664 | byte[] particleSystem, | ||
665 | byte clickAction, byte material, byte[] textureanim, bool attachment, | ||
666 | uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, | ||
667 | double SoundRadius, double priority) | ||
668 | { | ||
669 | this.m_regionHandle = regionHandle; | ||
670 | this.m_timeDilation = timeDilation; | ||
671 | this.m_localID = localID; | ||
672 | this.m_primShape = primShape; | ||
673 | this.m_pos = pos; | ||
674 | this.m_vel = vel; | ||
675 | this.m_acc = acc; | ||
676 | this.m_rotation = rotation; | ||
677 | this.m_rvel = rvel; | ||
678 | this.m_flags = (PrimFlags)flags; | ||
679 | this.m_objectID = objectID; | ||
680 | this.m_ownerID = ownerID; | ||
681 | this.m_text = text; | ||
682 | this.m_color = color; | ||
683 | this.m_parentID = parentID; | ||
684 | this.m_particleSystem = particleSystem; | ||
685 | this.m_clickAction = clickAction; | ||
686 | this.m_material = material; | ||
687 | this.m_textureanim = textureanim; | ||
688 | this.m_attachment = attachment; | ||
689 | this.m_AttachPoint = AttachPoint; | ||
690 | this.m_AssetId = AssetId; | ||
691 | this.m_SoundId = SoundId; | ||
692 | this.m_SoundVolume = SoundVolume; | ||
693 | this.m_SoundFlags = SoundFlags; | ||
694 | this.m_SoundRadius = SoundRadius; | ||
695 | this.m_priority = priority; | ||
696 | } | ||
697 | |||
698 | public ulong regionHandle { get { return this.m_regionHandle; } } | ||
699 | public ushort timeDilation { get { return this.m_timeDilation; } } | ||
700 | public uint localID { get { return this.m_localID; } } | ||
701 | public PrimitiveBaseShape primShape { get { return this.m_primShape; } } | ||
702 | public Vector3 pos { get { return this.m_pos; } } | ||
703 | public Vector3 vel { get { return this.m_vel; } } | ||
704 | public Vector3 acc { get { return this.m_acc; } } | ||
705 | public Quaternion rotation { get { return this.m_rotation; } } | ||
706 | public Vector3 rvel { get { return this.m_rvel; } } | ||
707 | public PrimFlags flags { get { return this.m_flags; } } | ||
708 | public UUID objectID { get { return this.m_objectID; } } | ||
709 | public UUID ownerID { get { return this.m_ownerID; } } | ||
710 | public string text { get { return this.m_text; } } | ||
711 | public byte[] color { get { return this.m_color; } } | ||
712 | public uint parentID { get { return this.m_parentID; } } | ||
713 | public byte[] particleSystem { get { return this.m_particleSystem; } } | ||
714 | public byte clickAction { get { return this.m_clickAction; } } | ||
715 | public byte material { get { return this.m_material; } } | ||
716 | public byte[] textureanim { get { return this.m_textureanim; } } | ||
717 | public bool attachment { get { return this.m_attachment; } } | ||
718 | public uint AttachPoint { get { return this.m_AttachPoint; } } | ||
719 | public UUID AssetId { get { return this.m_AssetId; } } | ||
720 | public UUID SoundId { get { return this.m_SoundId; } } | ||
721 | public double SoundVolume { get { return this.m_SoundVolume; } } | ||
722 | public byte SoundFlags { get { return this.m_SoundFlags; } } | ||
723 | public double SoundRadius { get { return this.m_SoundRadius; } } | ||
724 | public double priority { get { return this.m_priority; } } | ||
725 | } | ||
726 | |||
727 | public struct UpdatePriorityData { | ||
728 | private double m_priority; | ||
729 | private uint m_localID; | ||
730 | |||
731 | public UpdatePriorityData(double priority, uint localID) { | ||
732 | this.m_priority = priority; | ||
733 | this.m_localID = localID; | ||
734 | } | ||
735 | |||
736 | public double priority { get { return this.m_priority; } } | ||
737 | public uint localID { get { return this.m_localID; } } | ||
738 | } | ||
739 | |||
740 | [Flags] | ||
741 | public enum StateUpdateTypes | ||
742 | { | ||
743 | None = 0, | ||
744 | AvatarTerse = 1, | ||
745 | PrimitiveTerse = AvatarTerse << 1, | ||
746 | PrimitiveFull = PrimitiveTerse << 1, | ||
747 | All = AvatarTerse | PrimitiveTerse | PrimitiveFull, | ||
748 | } | ||
749 | |||
520 | public interface IClientAPI | 750 | public interface IClientAPI |
521 | { | 751 | { |
522 | Vector3 StartPos { get; set; } | 752 | Vector3 StartPos { get; set; } |
@@ -878,37 +1108,20 @@ namespace OpenSim.Framework | |||
878 | void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance); | 1108 | void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance); |
879 | void SendPayPrice(UUID objectID, int[] payPrice); | 1109 | void SendPayPrice(UUID objectID, int[] payPrice); |
880 | 1110 | ||
881 | void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | 1111 | void SendAvatarData(SendAvatarData data); |
882 | uint avatarLocalID, | ||
883 | Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation); | ||
884 | 1112 | ||
885 | void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, | 1113 | void SendAvatarTerseUpdate(SendAvatarTerseData data); |
886 | Vector3 velocity, Quaternion rotation, UUID agentid); | ||
887 | 1114 | ||
888 | void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations); | 1115 | void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations); |
889 | 1116 | ||
890 | void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID); | 1117 | void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID); |
891 | void SetChildAgentThrottle(byte[] throttle); | 1118 | void SetChildAgentThrottle(byte[] throttle); |
892 | 1119 | ||
893 | void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | 1120 | void SendPrimitiveToClient(SendPrimitiveData data); |
894 | Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||
895 | uint flags, | ||
896 | UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, | ||
897 | byte[] particleSystem, | ||
898 | byte clickAction, byte material, byte[] textureanim, bool attachment, | ||
899 | uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, | ||
900 | double SoundRadius); | ||
901 | |||
902 | |||
903 | void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
904 | Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||
905 | uint flags, UUID objectID, UUID ownerID, string text, byte[] color, | ||
906 | uint parentID, byte[] particleSystem, byte clickAction, byte material); | ||
907 | 1121 | ||
1122 | void SendPrimTerseUpdate(SendPrimitiveTerseData data); | ||
908 | 1123 | ||
909 | void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, | 1124 | void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler); |
910 | Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, | ||
911 | UUID AssetId, UUID owner, int attachPoint); | ||
912 | 1125 | ||
913 | void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, | 1126 | void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, |
914 | List<InventoryFolderBase> folders, bool fetchFolders, | 1127 | List<InventoryFolderBase> folders, bool fetchFolders, |
diff --git a/OpenSim/Framework/Location.cs b/OpenSim/Framework/Location.cs index 62ab5c7..9504e03 100644 --- a/OpenSim/Framework/Location.cs +++ b/OpenSim/Framework/Location.cs | |||
@@ -98,7 +98,7 @@ namespace OpenSim.Framework | |||
98 | 98 | ||
99 | public override int GetHashCode() | 99 | public override int GetHashCode() |
100 | { | 100 | { |
101 | return X.GetHashCode() * 29 + Y.GetHashCode(); | 101 | return X.GetHashCode() ^ Y.GetHashCode(); |
102 | } | 102 | } |
103 | 103 | ||
104 | public object Clone() | 104 | public object Clone() |
diff --git a/OpenSim/Framework/MainServer.cs b/OpenSim/Framework/MainServer.cs index b5f947e..7da4893 100644 --- a/OpenSim/Framework/MainServer.cs +++ b/OpenSim/Framework/MainServer.cs | |||
@@ -26,17 +26,36 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Framework.Servers.HttpServer; | 28 | using OpenSim.Framework.Servers.HttpServer; |
29 | using System.Collections.Generic; | ||
29 | 30 | ||
30 | namespace OpenSim.Framework | 31 | namespace OpenSim.Framework |
31 | { | 32 | { |
32 | public class MainServer | 33 | public class MainServer |
33 | { | 34 | { |
34 | private static BaseHttpServer instance; | 35 | private static BaseHttpServer instance; |
36 | private static Dictionary<uint, BaseHttpServer> m_Servers = | ||
37 | new Dictionary<uint, BaseHttpServer>(); | ||
35 | 38 | ||
36 | public static BaseHttpServer Instance | 39 | public static BaseHttpServer Instance |
37 | { | 40 | { |
38 | get { return instance; } | 41 | get { return instance; } |
39 | set { instance = value; } | 42 | set { instance = value; } |
40 | } | 43 | } |
44 | |||
45 | public static IHttpServer GetHttpServer(uint port) | ||
46 | { | ||
47 | if (port == 0) | ||
48 | return Instance; | ||
49 | if (port == Instance.Port) | ||
50 | return Instance; | ||
51 | |||
52 | if (m_Servers.ContainsKey(port)) | ||
53 | return m_Servers[port]; | ||
54 | |||
55 | m_Servers[port] = new BaseHttpServer(port); | ||
56 | m_Servers[port].Start(); | ||
57 | |||
58 | return m_Servers[port]; | ||
59 | } | ||
41 | } | 60 | } |
42 | } | 61 | } |
diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs new file mode 100755 index 0000000..ad39bbc --- /dev/null +++ b/OpenSim/Framework/MinHeap.cs | |||
@@ -0,0 +1,375 @@ | |||
1 | using System; | ||
2 | using System.Threading; | ||
3 | using System.Collections; | ||
4 | using System.Collections.Generic; | ||
5 | using System.Runtime.InteropServices; | ||
6 | |||
7 | namespace OpenSim.Framework | ||
8 | { | ||
9 | public interface IHandle { } | ||
10 | |||
11 | [Serializable, ComVisible(false)] | ||
12 | public class MinHeap<T> : ICollection<T>, ICollection | ||
13 | { | ||
14 | private class Handle : IHandle | ||
15 | { | ||
16 | internal int index = -1; | ||
17 | internal MinHeap<T> heap = null; | ||
18 | |||
19 | internal void Clear() | ||
20 | { | ||
21 | this.index = -1; | ||
22 | this.heap = null; | ||
23 | } | ||
24 | } | ||
25 | |||
26 | private struct HeapItem | ||
27 | { | ||
28 | internal T value; | ||
29 | internal Handle handle; | ||
30 | |||
31 | internal HeapItem(T value, Handle handle) | ||
32 | { | ||
33 | this.value = value; | ||
34 | this.handle = handle; | ||
35 | } | ||
36 | |||
37 | internal void Clear() | ||
38 | { | ||
39 | this.value = default(T); | ||
40 | if (this.handle != null) | ||
41 | { | ||
42 | this.handle.Clear(); | ||
43 | this.handle = null; | ||
44 | } | ||
45 | } | ||
46 | } | ||
47 | |||
48 | public const int DEFAULT_CAPACITY = 4; | ||
49 | |||
50 | private HeapItem[] items; | ||
51 | private int size; | ||
52 | private object sync_root; | ||
53 | private int version; | ||
54 | |||
55 | private Comparison<T> comparison; | ||
56 | |||
57 | public MinHeap() : this(DEFAULT_CAPACITY, Comparer<T>.Default) { } | ||
58 | public MinHeap(int capacity) : this(capacity, Comparer<T>.Default) { } | ||
59 | public MinHeap(IComparer<T> comparer) : this(DEFAULT_CAPACITY, comparer) { } | ||
60 | public MinHeap(int capacity, IComparer<T> comparer) : | ||
61 | this(capacity, new Comparison<T>(comparer.Compare)) { } | ||
62 | public MinHeap(Comparison<T> comparison) : this(DEFAULT_CAPACITY, comparison) { } | ||
63 | public MinHeap(int capacity, Comparison<T> comparison) | ||
64 | { | ||
65 | this.items = new HeapItem[capacity]; | ||
66 | this.comparison = comparison; | ||
67 | this.size = this.version = 0; | ||
68 | } | ||
69 | |||
70 | public int Count { get { return this.size; } } | ||
71 | |||
72 | public bool IsReadOnly { get { return false; } } | ||
73 | |||
74 | public bool IsSynchronized { get { return false; } } | ||
75 | |||
76 | public T this[IHandle key] | ||
77 | { | ||
78 | get | ||
79 | { | ||
80 | Handle handle = ValidateThisHandle(key); | ||
81 | return this.items[handle.index].value; | ||
82 | } | ||
83 | |||
84 | set | ||
85 | { | ||
86 | Handle handle = ValidateThisHandle(key); | ||
87 | this.items[handle.index].value = value; | ||
88 | if (!BubbleUp(handle.index)) | ||
89 | BubbleDown(handle.index); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | public object SyncRoot | ||
94 | { | ||
95 | get | ||
96 | { | ||
97 | if (this.sync_root == null) | ||
98 | Interlocked.CompareExchange<object>(ref this.sync_root, new object(), null); | ||
99 | return this.sync_root; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | private Handle ValidateHandle(IHandle ihandle) | ||
104 | { | ||
105 | if (ihandle == null) | ||
106 | throw new ArgumentNullException("handle"); | ||
107 | Handle handle = ihandle as Handle; | ||
108 | if (handle == null) | ||
109 | throw new InvalidOperationException("handle is not valid"); | ||
110 | return handle; | ||
111 | } | ||
112 | |||
113 | private Handle ValidateThisHandle(IHandle ihandle) | ||
114 | { | ||
115 | Handle handle = ValidateHandle(ihandle); | ||
116 | if (!object.ReferenceEquals(handle.heap, this)) | ||
117 | throw new InvalidOperationException("handle is not valid for this heap"); | ||
118 | if (handle.index < 0) | ||
119 | throw new InvalidOperationException("handle is not associated to a value"); | ||
120 | return handle; | ||
121 | } | ||
122 | |||
123 | private void Set(HeapItem item, int index) | ||
124 | { | ||
125 | this.items[index] = item; | ||
126 | if (item.handle != null) | ||
127 | item.handle.index = index; | ||
128 | } | ||
129 | |||
130 | private bool BubbleUp(int index) | ||
131 | { | ||
132 | HeapItem item = this.items[index]; | ||
133 | int current, parent; | ||
134 | |||
135 | for (current = index, parent = (current - 1) / 2; | ||
136 | (current > 0) && (this.comparison(this.items[parent].value, item.value)) > 0; | ||
137 | current = parent, parent = (current - 1) / 2) | ||
138 | { | ||
139 | Set(this.items[parent], current); | ||
140 | } | ||
141 | |||
142 | if (current != index) | ||
143 | { | ||
144 | Set(item, current); | ||
145 | ++this.version; | ||
146 | return true; | ||
147 | } | ||
148 | return false; | ||
149 | } | ||
150 | |||
151 | private void BubbleDown(int index) | ||
152 | { | ||
153 | HeapItem item = this.items[index]; | ||
154 | int current, child; | ||
155 | |||
156 | for (current = index, child = (2 * current) + 1; | ||
157 | current < this.size / 2; | ||
158 | current = child, child = (2 * current) + 1) | ||
159 | { | ||
160 | if ((child < this.size - 1) && this.comparison(this.items[child].value, this.items[child + 1].value) > 0) | ||
161 | ++child; | ||
162 | if (this.comparison(this.items[child].value, item.value) >= 0) | ||
163 | break; | ||
164 | Set(this.items[child], current); | ||
165 | } | ||
166 | |||
167 | if (current != index) | ||
168 | { | ||
169 | Set(item, current); | ||
170 | ++this.version; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | public bool TryGetValue(IHandle key, out T value) | ||
175 | { | ||
176 | Handle handle = ValidateHandle(key); | ||
177 | if (handle.index > -1) | ||
178 | { | ||
179 | value = this.items[handle.index].value; | ||
180 | return true; | ||
181 | } | ||
182 | value = default(T); | ||
183 | return false; | ||
184 | } | ||
185 | |||
186 | public bool ContainsHandle(IHandle ihandle) | ||
187 | { | ||
188 | Handle handle = ValidateHandle(ihandle); | ||
189 | return object.ReferenceEquals(handle.heap, this) && handle.index > -1; | ||
190 | } | ||
191 | |||
192 | public void Add(T value, ref IHandle handle) | ||
193 | { | ||
194 | if (handle == null) | ||
195 | handle = new Handle(); | ||
196 | Add(value, handle); | ||
197 | } | ||
198 | |||
199 | public void Add(T value, IHandle ihandle) | ||
200 | { | ||
201 | if (this.size == this.items.Length) | ||
202 | { | ||
203 | int capacity = (int)((this.items.Length * 200L) / 100L); | ||
204 | if (capacity < (this.items.Length + DEFAULT_CAPACITY)) | ||
205 | capacity = this.items.Length + DEFAULT_CAPACITY; | ||
206 | Array.Resize<HeapItem>(ref this.items, capacity); | ||
207 | } | ||
208 | |||
209 | Handle handle = null; | ||
210 | if (ihandle != null) | ||
211 | { | ||
212 | handle = ValidateHandle(ihandle); | ||
213 | handle.heap = this; | ||
214 | } | ||
215 | |||
216 | HeapItem item = new MinHeap<T>.HeapItem(value, handle); | ||
217 | |||
218 | Set(item, this.size); | ||
219 | BubbleUp(this.size++); | ||
220 | } | ||
221 | |||
222 | public void Add(T value) | ||
223 | { | ||
224 | Add(value, null); | ||
225 | } | ||
226 | |||
227 | public T Min() | ||
228 | { | ||
229 | if (this.size == 0) | ||
230 | throw new InvalidOperationException("Heap is empty"); | ||
231 | |||
232 | return this.items[0].value; | ||
233 | } | ||
234 | |||
235 | public void Clear() | ||
236 | { | ||
237 | for (int index = 0; index < this.size; ++index) | ||
238 | this.items[index].Clear(); | ||
239 | this.size = 0; | ||
240 | ++this.version; | ||
241 | } | ||
242 | |||
243 | public void TrimExcess() | ||
244 | { | ||
245 | int length = (int)(this.items.Length * 0.9); | ||
246 | if (this.size < length) | ||
247 | Array.Resize<HeapItem>(ref this.items, Math.Min(this.size, DEFAULT_CAPACITY)); | ||
248 | } | ||
249 | |||
250 | private void RemoveAt(int index) | ||
251 | { | ||
252 | if (this.size == 0) | ||
253 | throw new InvalidOperationException("Heap is empty"); | ||
254 | if (index >= this.size) | ||
255 | throw new ArgumentOutOfRangeException("index"); | ||
256 | |||
257 | this.items[index].Clear(); | ||
258 | if (--this.size > 0 && index != this.size) | ||
259 | { | ||
260 | Set(this.items[this.size], index); | ||
261 | if (!BubbleUp(index)) | ||
262 | BubbleDown(index); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | public T RemoveMin() | ||
267 | { | ||
268 | if (this.size == 0) | ||
269 | throw new InvalidOperationException("Heap is empty"); | ||
270 | |||
271 | HeapItem item = this.items[0]; | ||
272 | RemoveAt(0); | ||
273 | return item.value; | ||
274 | } | ||
275 | |||
276 | public T Remove(IHandle ihandle) | ||
277 | { | ||
278 | Handle handle = ValidateThisHandle(ihandle); | ||
279 | HeapItem item = this.items[handle.index]; | ||
280 | RemoveAt(handle.index); | ||
281 | return item.value; | ||
282 | } | ||
283 | |||
284 | private int GetIndex(T value) | ||
285 | { | ||
286 | EqualityComparer<T> comparer = EqualityComparer<T>.Default; | ||
287 | int index; | ||
288 | |||
289 | for (index = 0; index < this.size; ++index) | ||
290 | { | ||
291 | if (comparer.Equals(this.items[index].value, value)) | ||
292 | return index; | ||
293 | } | ||
294 | return -1; | ||
295 | } | ||
296 | |||
297 | public bool Contains(T value) | ||
298 | { | ||
299 | return GetIndex(value) != -1; | ||
300 | } | ||
301 | |||
302 | public bool Remove(T value) | ||
303 | { | ||
304 | int index = GetIndex(value); | ||
305 | if (index != -1) | ||
306 | { | ||
307 | RemoveAt(index); | ||
308 | return true; | ||
309 | } | ||
310 | return false; | ||
311 | } | ||
312 | |||
313 | public void CopyTo(T[] array, int index) | ||
314 | { | ||
315 | if (array == null) | ||
316 | throw new ArgumentNullException("array"); | ||
317 | if (array.Rank != 1) | ||
318 | throw new ArgumentException("Multidimensional array not supported"); | ||
319 | if (array.GetLowerBound(0) != 0) | ||
320 | throw new ArgumentException("Non-zero lower bound array not supported"); | ||
321 | |||
322 | int length = array.Length; | ||
323 | if ((index < 0) || (index > length)) | ||
324 | throw new ArgumentOutOfRangeException("index"); | ||
325 | if ((length - index) < this.size) | ||
326 | throw new ArgumentException("Not enough space available in array starting at index"); | ||
327 | |||
328 | for (int i = 0; i < this.size; ++i) | ||
329 | array[index + i] = this.items[i].value; | ||
330 | } | ||
331 | |||
332 | public void CopyTo(Array array, int index) | ||
333 | { | ||
334 | if (array == null) | ||
335 | throw new ArgumentNullException("array"); | ||
336 | if (array.Rank != 1) | ||
337 | throw new ArgumentException("Multidimensional array not supported"); | ||
338 | if (array.GetLowerBound(0) != 0) | ||
339 | throw new ArgumentException("Non-zero lower bound array not supported"); | ||
340 | |||
341 | int length = array.Length; | ||
342 | if ((index < 0) || (index > length)) | ||
343 | throw new ArgumentOutOfRangeException("index"); | ||
344 | if ((length - index) < this.size) | ||
345 | throw new ArgumentException("Not enough space available in array starting at index"); | ||
346 | |||
347 | try | ||
348 | { | ||
349 | for (int i = 0; i < this.size; ++i) | ||
350 | array.SetValue(this.items[i].value, index + i); | ||
351 | } | ||
352 | catch (ArrayTypeMismatchException) | ||
353 | { | ||
354 | throw new ArgumentException("Invalid array type"); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | public IEnumerator<T> GetEnumerator() | ||
359 | { | ||
360 | int version = this.version; | ||
361 | |||
362 | for (int index = 0; index < this.size; ++index) | ||
363 | { | ||
364 | if (version != this.version) | ||
365 | throw new InvalidOperationException("Heap was modified while enumerating"); | ||
366 | yield return this.items[index].value; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | IEnumerator IEnumerable.GetEnumerator() | ||
371 | { | ||
372 | return GetEnumerator(); | ||
373 | } | ||
374 | } | ||
375 | } | ||
diff --git a/OpenSim/Framework/Parallel.cs b/OpenSim/Framework/Parallel.cs index 6efdad0..70eecdc 100644 --- a/OpenSim/Framework/Parallel.cs +++ b/OpenSim/Framework/Parallel.cs | |||
@@ -36,7 +36,7 @@ namespace OpenSim.Framework | |||
36 | /// </summary> | 36 | /// </summary> |
37 | public static class Parallel | 37 | public static class Parallel |
38 | { | 38 | { |
39 | private static readonly int processorCount = System.Environment.ProcessorCount; | 39 | public static readonly int ProcessorCount = System.Environment.ProcessorCount; |
40 | 40 | ||
41 | /// <summary> | 41 | /// <summary> |
42 | /// Executes a for loop in which iterations may run in parallel | 42 | /// Executes a for loop in which iterations may run in parallel |
@@ -46,7 +46,7 @@ namespace OpenSim.Framework | |||
46 | /// <param name="body">Method body to run for each iteration of the loop</param> | 46 | /// <param name="body">Method body to run for each iteration of the loop</param> |
47 | public static void For(int fromInclusive, int toExclusive, Action<int> body) | 47 | public static void For(int fromInclusive, int toExclusive, Action<int> body) |
48 | { | 48 | { |
49 | For(processorCount, fromInclusive, toExclusive, body); | 49 | For(ProcessorCount, fromInclusive, toExclusive, body); |
50 | } | 50 | } |
51 | 51 | ||
52 | /// <summary> | 52 | /// <summary> |
@@ -66,7 +66,7 @@ namespace OpenSim.Framework | |||
66 | 66 | ||
67 | for (int i = 0; i < threadCount; i++) | 67 | for (int i = 0; i < threadCount; i++) |
68 | { | 68 | { |
69 | ThreadPool.QueueUserWorkItem( | 69 | Util.FireAndForget( |
70 | delegate(object o) | 70 | delegate(object o) |
71 | { | 71 | { |
72 | int threadIndex = (int)o; | 72 | int threadIndex = (int)o; |
@@ -103,7 +103,7 @@ namespace OpenSim.Framework | |||
103 | /// <param name="body">Method body to run for each object in the collection</param> | 103 | /// <param name="body">Method body to run for each object in the collection</param> |
104 | public static void ForEach<T>(IEnumerable<T> enumerable, Action<T> body) | 104 | public static void ForEach<T>(IEnumerable<T> enumerable, Action<T> body) |
105 | { | 105 | { |
106 | ForEach<T>(processorCount, enumerable, body); | 106 | ForEach<T>(ProcessorCount, enumerable, body); |
107 | } | 107 | } |
108 | 108 | ||
109 | /// <summary> | 109 | /// <summary> |
@@ -122,7 +122,7 @@ namespace OpenSim.Framework | |||
122 | 122 | ||
123 | for (int i = 0; i < threadCount; i++) | 123 | for (int i = 0; i < threadCount; i++) |
124 | { | 124 | { |
125 | ThreadPool.QueueUserWorkItem( | 125 | Util.FireAndForget( |
126 | delegate(object o) | 126 | delegate(object o) |
127 | { | 127 | { |
128 | int threadIndex = (int)o; | 128 | int threadIndex = (int)o; |
@@ -161,7 +161,7 @@ namespace OpenSim.Framework | |||
161 | /// <param name="actions">A series of method bodies to execute</param> | 161 | /// <param name="actions">A series of method bodies to execute</param> |
162 | public static void Invoke(params Action[] actions) | 162 | public static void Invoke(params Action[] actions) |
163 | { | 163 | { |
164 | Invoke(processorCount, actions); | 164 | Invoke(ProcessorCount, actions); |
165 | } | 165 | } |
166 | 166 | ||
167 | /// <summary> | 167 | /// <summary> |
@@ -178,7 +178,7 @@ namespace OpenSim.Framework | |||
178 | 178 | ||
179 | for (int i = 0; i < threadCount; i++) | 179 | for (int i = 0; i < threadCount; i++) |
180 | { | 180 | { |
181 | ThreadPool.QueueUserWorkItem( | 181 | Util.FireAndForget( |
182 | delegate(object o) | 182 | delegate(object o) |
183 | { | 183 | { |
184 | int threadIndex = (int)o; | 184 | int threadIndex = (int)o; |
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index a7315f5..721233d 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs | |||
@@ -821,7 +821,7 @@ namespace OpenSim.Framework | |||
821 | "Scope ID for this region", ScopeID.ToString(), true); | 821 | "Scope ID for this region", ScopeID.ToString(), true); |
822 | 822 | ||
823 | configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING, | 823 | configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING, |
824 | "Region Type", String.Empty, true); | 824 | "Free form string describing the type of region", String.Empty, true); |
825 | } | 825 | } |
826 | 826 | ||
827 | public void loadConfigurationOptions() | 827 | public void loadConfigurationOptions() |
@@ -978,11 +978,12 @@ namespace OpenSim.Framework | |||
978 | 978 | ||
979 | public void SaveLastMapUUID(UUID mapUUID) | 979 | public void SaveLastMapUUID(UUID mapUUID) |
980 | { | 980 | { |
981 | if (null == configMember) return; | ||
982 | |||
983 | lastMapUUID = mapUUID; | 981 | lastMapUUID = mapUUID; |
984 | lastMapRefresh = Util.UnixTimeSinceEpoch().ToString(); | 982 | lastMapRefresh = Util.UnixTimeSinceEpoch().ToString(); |
985 | 983 | ||
984 | if (configMember == null) | ||
985 | return; | ||
986 | |||
986 | configMember.forceSetConfigurationOption("lastmap_uuid", mapUUID.ToString()); | 987 | configMember.forceSetConfigurationOption("lastmap_uuid", mapUUID.ToString()); |
987 | configMember.forceSetConfigurationOption("lastmap_refresh", lastMapRefresh); | 988 | configMember.forceSetConfigurationOption("lastmap_refresh", lastMapRefresh); |
988 | } | 989 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 942fed9..85d7be2 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -1609,7 +1609,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1609 | //while (true) | 1609 | //while (true) |
1610 | //{ | 1610 | //{ |
1611 | // context = m_httpListener.GetContext(); | 1611 | // context = m_httpListener.GetContext(); |
1612 | // ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context); | 1612 | // ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(HandleRequest), context); |
1613 | // } | 1613 | // } |
1614 | } | 1614 | } |
1615 | catch (Exception e) | 1615 | catch (Exception e) |
diff --git a/OpenSim/Framework/ThrottleOutPacketType.cs b/OpenSim/Framework/ThrottleOutPacketType.cs index e21ff32..d56231a 100644 --- a/OpenSim/Framework/ThrottleOutPacketType.cs +++ b/OpenSim/Framework/ThrottleOutPacketType.cs | |||
@@ -51,4 +51,16 @@ namespace OpenSim.Framework | |||
51 | /// <remarks>This is a sub-category of Task</remarks> | 51 | /// <remarks>This is a sub-category of Task</remarks> |
52 | State = 7, | 52 | State = 7, |
53 | } | 53 | } |
54 | |||
55 | [Flags] | ||
56 | public enum ThrottleOutPacketTypeFlags | ||
57 | { | ||
58 | Land = 1 << 0, | ||
59 | Wind = 1 << 1, | ||
60 | Cloud = 1 << 2, | ||
61 | Task = 1 << 3, | ||
62 | Texture = 1 << 4, | ||
63 | Asset = 1 << 5, | ||
64 | State = 1 << 6, | ||
65 | } | ||
54 | } | 66 | } |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 38729c6..d09bd6d 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -41,19 +41,36 @@ using System.Security.Cryptography; | |||
41 | using System.Text; | 41 | using System.Text; |
42 | using System.Text.RegularExpressions; | 42 | using System.Text.RegularExpressions; |
43 | using System.Xml; | 43 | using System.Xml; |
44 | using System.Threading; | ||
44 | using log4net; | 45 | using log4net; |
45 | using Nini.Config; | 46 | using Nini.Config; |
46 | using Nwc.XmlRpc; | 47 | using Nwc.XmlRpc; |
48 | using BclExtras; | ||
47 | using OpenMetaverse; | 49 | using OpenMetaverse; |
48 | using OpenMetaverse.StructuredData; | 50 | using OpenMetaverse.StructuredData; |
51 | using Amib.Threading; | ||
49 | 52 | ||
50 | namespace OpenSim.Framework | 53 | namespace OpenSim.Framework |
51 | { | 54 | { |
52 | /// <summary> | 55 | /// <summary> |
56 | /// The method used by Util.FireAndForget for asynchronously firing events | ||
57 | /// </summary> | ||
58 | public enum FireAndForgetMethod | ||
59 | { | ||
60 | UnsafeQueueUserWorkItem, | ||
61 | QueueUserWorkItem, | ||
62 | BeginInvoke, | ||
63 | SmartThreadPool, | ||
64 | Thread, | ||
65 | } | ||
66 | |||
67 | /// <summary> | ||
53 | /// Miscellaneous utility functions | 68 | /// Miscellaneous utility functions |
54 | /// </summary> | 69 | /// </summary> |
55 | public class Util | 70 | public class Util |
56 | { | 71 | { |
72 | private static SmartThreadPool m_ThreadPool = null; | ||
73 | |||
57 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 74 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
58 | 75 | ||
59 | private static uint nextXferID = 5000; | 76 | private static uint nextXferID = 5000; |
@@ -69,7 +86,9 @@ namespace OpenSim.Framework | |||
69 | 86 | ||
70 | public static readonly Regex UUIDPattern | 87 | public static readonly Regex UUIDPattern |
71 | = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); | 88 | = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); |
72 | 89 | ||
90 | public static FireAndForgetMethod FireAndForgetMethod = FireAndForgetMethod.SmartThreadPool; | ||
91 | |||
73 | /// <summary> | 92 | /// <summary> |
74 | /// Linear interpolates B<->C using percent A | 93 | /// Linear interpolates B<->C using percent A |
75 | /// </summary> | 94 | /// </summary> |
@@ -1269,24 +1288,78 @@ namespace OpenSim.Framework | |||
1269 | 1288 | ||
1270 | #region FireAndForget Threading Pattern | 1289 | #region FireAndForget Threading Pattern |
1271 | 1290 | ||
1272 | public static void FireAndForget(System.Threading.WaitCallback callback) | 1291 | /// <summary> |
1292 | /// Created to work around a limitation in Mono with nested delegates | ||
1293 | /// </summary> | ||
1294 | private class FireAndForgetWrapper | ||
1273 | { | 1295 | { |
1274 | callback.BeginInvoke(null, EndFireAndForget, callback); | 1296 | public void FireAndForget(System.Threading.WaitCallback callback) |
1297 | { | ||
1298 | callback.BeginInvoke(null, EndFireAndForget, callback); | ||
1299 | } | ||
1300 | |||
1301 | public void FireAndForget(System.Threading.WaitCallback callback, object obj) | ||
1302 | { | ||
1303 | callback.BeginInvoke(obj, EndFireAndForget, callback); | ||
1304 | } | ||
1305 | |||
1306 | private static void EndFireAndForget(IAsyncResult ar) | ||
1307 | { | ||
1308 | System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState; | ||
1309 | |||
1310 | try { callback.EndInvoke(ar); } | ||
1311 | catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); } | ||
1312 | |||
1313 | ar.AsyncWaitHandle.Close(); | ||
1314 | } | ||
1275 | } | 1315 | } |
1276 | 1316 | ||
1277 | public static void FireAndForget(System.Threading.WaitCallback callback, object obj) | 1317 | public static void FireAndForget(System.Threading.WaitCallback callback) |
1278 | { | 1318 | { |
1279 | callback.BeginInvoke(obj, EndFireAndForget, callback); | 1319 | FireAndForget(callback, null); |
1280 | } | 1320 | } |
1281 | 1321 | ||
1282 | private static void EndFireAndForget(IAsyncResult ar) | 1322 | public static void SetMaxThreads(int maxThreads) |
1283 | { | 1323 | { |
1284 | System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState; | 1324 | if (m_ThreadPool != null) |
1325 | return; | ||
1326 | |||
1327 | STPStartInfo startInfo = new STPStartInfo(); | ||
1328 | startInfo.IdleTimeout = 2000; // 2 seconds | ||
1329 | startInfo.MaxWorkerThreads = maxThreads; | ||
1330 | startInfo.MinWorkerThreads = 2; | ||
1331 | startInfo.StackSize = 524288; | ||
1332 | startInfo.ThreadPriority = ThreadPriority.Normal; | ||
1285 | 1333 | ||
1286 | try { callback.EndInvoke(ar); } | 1334 | startInfo.StartSuspended = false; |
1287 | catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); } | 1335 | |
1336 | m_ThreadPool = new SmartThreadPool(startInfo); | ||
1337 | } | ||
1288 | 1338 | ||
1289 | ar.AsyncWaitHandle.Close(); | 1339 | public static void FireAndForget(System.Threading.WaitCallback callback, object obj) |
1340 | { | ||
1341 | switch (FireAndForgetMethod) | ||
1342 | { | ||
1343 | case FireAndForgetMethod.UnsafeQueueUserWorkItem: | ||
1344 | System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj); | ||
1345 | break; | ||
1346 | case FireAndForgetMethod.QueueUserWorkItem: | ||
1347 | System.Threading.ThreadPool.QueueUserWorkItem(callback, obj); | ||
1348 | break; | ||
1349 | case FireAndForgetMethod.BeginInvoke: | ||
1350 | FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>(); | ||
1351 | wrapper.FireAndForget(callback, obj); | ||
1352 | break; | ||
1353 | case FireAndForgetMethod.SmartThreadPool: | ||
1354 | m_ThreadPool.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj); | ||
1355 | break; | ||
1356 | case FireAndForgetMethod.Thread: | ||
1357 | System.Threading.Thread thread = new System.Threading.Thread(delegate(object o) { callback(o); }); | ||
1358 | thread.Start(obj); | ||
1359 | break; | ||
1360 | default: | ||
1361 | throw new NotImplementedException(); | ||
1362 | } | ||
1290 | } | 1363 | } |
1291 | 1364 | ||
1292 | #endregion FireAndForget Threading Pattern | 1365 | #endregion FireAndForget Threading Pattern |