Changeset 1590


Ignore:
Timestamp:
Jun 5, 2010, 3:19:15 PM (12 years ago)
Author:
kopal
Message:
  • replaced own threading in ExecutionEngine with Gears4Net
Location:
trunk/CrypPlugins/WorkspaceManager
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/WorkspaceManager/Execution/ExecutionEngine.cs

    r1562 r1590  
    2525using Cryptool.PluginBase;
    2626using System.Reflection;
     27using Gears4Net;
    2728
    2829namespace WorkspaceManager.Execution
     
    3334    public class ExecutionEngine
    3435    {
    35         private Hashtable RunningPlugins = Hashtable.Synchronized(new Hashtable());
    3636        private WorkspaceManager WorkspaceManagerEditor;
    37         private Mutex mutex = new Mutex();
    38 
    39         /// <summary>
    40         /// Enable/Disable the Debug Mode
    41         /// </summary>
    42         public bool DebugMode { get; set; }
    43 
     37        private Scheduler scheduler;
     38     
    4439        /// <summary>
    4540        /// Creates a new ExecutionEngine
     
    6560        /// <param name="workspaceModel"></param>
    6661        public void Execute(WorkspaceModel workspaceModel)
    67         {           
    68             RunningPlugins.Clear();
    69             GuiLogMessage("ExecutionEngine starts", NotificationLevel.Debug);
    70             ThreadPool.SetMaxThreads(1, 1);
    71             ThreadPool.QueueUserWorkItem(new WaitCallback(Schedule), workspaceModel);
    72         }
    73 
    74         /// <summary>
    75         /// Scheduler Thread
    76         /// </summary>
    77         /// <param name="stateInfo"></param>
    78         public void Schedule(object stateInfo)
    79         {
    80             WorkspaceModel workspaceModel = (WorkspaceModel)stateInfo;
     62        {
    8163            if (!IsRunning)
    8264            {
    8365                IsRunning = true;
     66                scheduler = new WinFormsScheduler("Scheduler");
    8467                workspaceModel.resetStates();
    85 
    86                 //Initially check if a plugin can be executed
     68               
    8769                foreach (PluginModel pluginModel in workspaceModel.AllPluginModels)
    8870                {
    89                     pluginModel.checkExecutable();
     71                    PluginProtocol pluginProtocol = new PluginProtocol(scheduler, pluginModel,this);
     72                    PluginModel.PluginProtocol = pluginProtocol;
     73                    scheduler.AddProtocol(pluginProtocol);
     74                    pluginModel.checkExecutable(pluginProtocol);
     75                    pluginProtocol.Start();
    9076                }
    91 
    92                 //Now start Plugins if they are executable
    93                 while (IsRunning)
    94                 {
    95                     foreach (PluginModel pluginModel in workspaceModel.AllPluginModels)
    96                     {
    97                        
    98                         //execute the plugin in a new Thread only if it is executable
    99                         if (IsRunning && pluginModel.ExecutionState == PluginModelState.Executable && !RunningPlugins.Contains(pluginModel))
    100                         {
    101                             AddRunningPlugin(pluginModel);
    102                             ThreadPool.QueueUserWorkItem(new WaitCallback(runPlugin), pluginModel);
    103                         }
    104                         Thread.Sleep(50);
    105                     }
    106                 }
    107                 GuiLogMessage("ExecutionEngine ends", NotificationLevel.Debug);
    10877            }
    109         }
    110 
    111         /// <summary>
    112         /// Runs a Plugin
    113         /// </summary>
    114         /// <param name="stateInfo"></param>
    115         private void runPlugin(object stateInfo)
    116         {   
    117          
    118             PluginModel pluginModel = (PluginModel)stateInfo;           
    119             GuiLogMessage("Running Plugin " + pluginModel.Name + " now!", NotificationLevel.Debug);
    120            
     78        }     
     79     
     80        /// <summary>
     81        /// Stop the execution
     82        /// </summary>
     83        public void Stop()
     84        {
     85            scheduler.Shutdown();
     86            IsRunning = false;   
     87        }
     88
     89        /// <summary>
     90        /// Pause the execution
     91        /// </summary>
     92        public void Pause()
     93        {
     94            //not implemented yet
     95        }
     96
     97        /// <summary>
     98        /// Use the logger of the WorkspaceManagerEditor
     99        /// </summary>
     100        /// <param name="message"></param>
     101        /// <param name="level"></param>
     102        public void GuiLogMessage(string message, NotificationLevel level)
     103        {           
     104            WorkspaceManagerEditor.GuiLogMessage(message, level);
     105        }           
     106    }
     107
     108    /// <summary>
     109    /// Message send to scheduler for a Plugin to trigger the PreExecution
     110    /// </summary>
     111    public class MessagePreExecution : MessageBase
     112    {
     113        public PluginModel PluginModel;
     114    }
     115
     116    /// <summary>
     117    /// Message send to scheduler for a Plugin to trigger the Execution
     118    /// </summary>
     119    public class MessageExecution : MessageBase
     120    {
     121        public PluginModel PluginModel;
     122    }
     123
     124    /// <summary>
     125    /// Message send to scheduler for a Plugin to trigger the PostExecution
     126    /// </summary>
     127    public class MessagePostExecution : MessageBase
     128    {
     129        public PluginModel PluginModel;
     130    }
     131
     132     /// <summary>
     133    /// A Protocol for a PluginModel
     134    /// </summary>
     135    public class PluginProtocol : ProtocolBase
     136    {
     137        private PluginModel pluginModel;
     138        private ExecutionEngine executionEngine;
     139
     140        /// <summary>
     141        /// Create a new protocol. Each protocol requires a scheduler which provides
     142        /// a thread for execution.
     143        /// </summary>
     144        /// <param name="scheduler"></param>
     145        public PluginProtocol(Scheduler scheduler, PluginModel pluginModel,ExecutionEngine executionEngine)
     146            : base(scheduler)
     147        {
     148            this.pluginModel = pluginModel;
     149            this.executionEngine = executionEngine;
     150        }
     151
     152        /// <summary>
     153        /// The main function of the protocol
     154        /// </summary>
     155        /// <param name="stateMachine"></param>
     156        /// <returns></returns>
     157        public override System.Collections.Generic.IEnumerator<ReceiverBase> Execute(AbstractStateMachine stateMachine)
     158        {
     159            yield return Receive<MessagePreExecution>(null, this.HandlePreExecute);
     160            MessageExecution msg_exec = new MessageExecution();
     161            msg_exec.PluginModel = this.pluginModel;
     162            this.BroadcastMessage(msg_exec);           
     163            yield return Receive<MessageExecution>(null, this.HandleExecute);
     164            MessagePostExecution msg_post = new MessagePostExecution();
     165            msg_post.PluginModel = this.pluginModel;
     166            this.BroadcastMessage(msg_post);   
     167            yield return Receive<MessagePreExecution>(null, this.HandlePostExecute);
     168        }
     169
     170        /// <summary>
     171        /// Handler function for a message.
     172        /// This handler must not block, because it executes inside the thread of the scheduler.
     173        /// </summary>
     174        /// <param name="msg"></param>
     175        private void HandlePreExecute(MessagePreExecution msg)
     176        {
     177            executionEngine.GuiLogMessage("HandlePreExecute for \"" + msg.PluginModel.Name + "\"", NotificationLevel.Debug);
     178            msg.PluginModel.Plugin.PreExecution();
     179        }
     180
     181        /// <summary>
     182        /// Handler function for a message.
     183        /// This handler must not block, because it executes inside the thread of the scheduler.
     184        /// </summary>
     185        /// <param name="msg"></param>
     186        private void HandleExecute(MessageExecution msg)
     187        {
     188            executionEngine.GuiLogMessage("HandleExecute for \"" + msg.PluginModel.Name + "\"", NotificationLevel.Debug);
    121189            //Fill the plugins Inputs with data
    122190            foreach (ConnectorModel connectorModel in pluginModel.InputConnectors)
    123191            {
    124192                if (connectorModel.HasData)
    125                 {                   
     193                {
    126194                    PropertyInfo propertyInfo = pluginModel.Plugin.GetType().GetProperty(connectorModel.PropertyName);
    127                     GuiLogMessage("Setting for " + connectorModel.PluginModel.Name + " the value of property " + propertyInfo.Name + " to \"" + connectorModel.Data +"\"", NotificationLevel.Debug);
    128                     propertyInfo.SetValue(pluginModel.Plugin, connectorModel.Data, null);   
     195                    propertyInfo.SetValue(pluginModel.Plugin, connectorModel.Data, null);
    129196                    connectorModel.Data = null;
    130197                    connectorModel.HasData = false;
     
    132199                }
    133200            }
    134 
    135             //Run execution
    136             try
    137             {
    138                 pluginModel.ExecutionState = PluginModelState.PreExecuting;
    139                 pluginModel.Plugin.PreExecution();
    140                 pluginModel.ExecutionState = PluginModelState.Executing;
    141                 pluginModel.Plugin.Execute();
    142                 pluginModel.ExecutionState = PluginModelState.PostExecuting;
    143                 pluginModel.Plugin.PostExecution();
    144                 pluginModel.ExecutionState = PluginModelState.Terminated;
    145             }
    146             catch (Exception ex)
    147             {
    148                 pluginModel.ExecutionState = PluginModelState.Error;
    149                 GuiLogMessage("Error during Execution of Plugin " + pluginModel.Name + ": " + ex.Message, NotificationLevel.Error);
    150             }
    151             //Remove plugin from being-executed-list so that it can be
    152             //executed again
    153             if (IsRunning)
    154             {
    155                 //we only remove the plugin if we are in state running;otherwise
    156                 //the Stop() method will remove it
    157                 RemoveRunningPlugin(pluginModel);
    158             }
    159             GuiLogMessage("Stopped Plugin " + pluginModel.Name, NotificationLevel.Debug);
    160             Thread.Sleep(15);
    161         }
    162 
    163         /// <summary>
    164         /// Stop the execution
    165         /// </summary>
    166         public void Stop()
    167         {
    168             mutex.WaitOne();
    169             IsRunning = false;
    170             foreach (PluginModel pluginModel in RunningPlugins.Keys)
    171             {
    172                 pluginModel.Plugin.Stop();             
    173             }
    174             RunningPlugins.Clear();
    175             mutex.ReleaseMutex();
    176         }
    177 
    178         /// <summary>
    179         /// Pause the execution
    180         /// </summary>
    181         public void Pause()
    182         {
    183             //not implemented yet
    184         }
    185 
    186         /// <summary>
    187         /// Use the logger of the WorkspaceManagerEditor
    188         /// </summary>
    189         /// <param name="message"></param>
    190         /// <param name="level"></param>
    191         private void GuiLogMessage(string message, NotificationLevel level)
    192         {
    193             if (DebugMode || level.Equals(NotificationLevel.Error) || level.Equals(NotificationLevel.Warning))
    194             {
    195                 WorkspaceManagerEditor.GuiLogMessage(message, level);
    196             }
    197         }
    198 
    199         /// <summary>
    200         /// Add a running plugin
    201         /// </summary>
    202         /// <param name="pluginModel"></param>
    203         private void AddRunningPlugin(PluginModel pluginModel)
    204         {
    205             mutex.WaitOne();
    206             if (IsRunning)
    207             {
    208                 RunningPlugins.Add(pluginModel, pluginModel);
    209             }
    210             mutex.ReleaseMutex();
    211         }
    212 
    213         /// <summary>
    214         /// Remove a running plugin
    215         /// </summary>
    216         /// <param name="pluginModel"></param>
    217         private void RemoveRunningPlugin(PluginModel pluginModel)
    218         {
    219             mutex.WaitOne();
    220             if(RunningPlugins.Contains(pluginModel))
    221             {
    222                 RunningPlugins.Remove(pluginModel);
    223             }
    224             mutex.ReleaseMutex();
    225         }
    226 
     201            msg.PluginModel.Plugin.Execute();
     202        }
     203
     204        /// <summary>
     205        /// Handler function for a message.
     206        /// This handler must not block, because it executes inside the thread of the scheduler.
     207        /// </summary>
     208        /// <param name="msg"></param>
     209        private void HandlePostExecute(MessagePreExecution msg)
     210        {
     211            executionEngine.GuiLogMessage("HandlePostExecute for \"" + msg.PluginModel.Name + "\"", NotificationLevel.Debug);
     212            msg.PluginModel.Plugin.PostExecution();
     213        }
    227214    }
    228215}
  • trunk/CrypPlugins/WorkspaceManager/Model/ConnectorModel.cs

    r1581 r1590  
    156156                    //We changed an input on the PluginModel where "To" is belonging to so
    157157                    //we have to check if this is executable now
    158                     connectionModel.To.PluginModel.checkExecutable();
     158                    connectionModel.To.PluginModel.checkExecutable(PluginModel.PluginProtocol);
    159159                }
    160160            }                       
  • trunk/CrypPlugins/WorkspaceManager/Model/PluginModel.cs

    r1584 r1590  
    2323using System.Threading;
    2424using System.Windows.Controls;
     25using Gears4Net;
     26using WorkspaceManager.Execution;
    2527
    2628namespace WorkspaceManager.Model
     
    3133    [Serializable]
    3234    public class PluginModel : VisualElementModel
    33     {
    34         [NonSerialized]
    35         private Mutex mutex = new Mutex();
    36 
     35    {       
    3736        [NonSerialized]
    3837        private IPlugin plugin;
    39 
    40         [NonSerialized]
    41         private PluginModelState executionstate = PluginModelState.Undefined;
    42 
     38     
    4339        private int imageIndex = 0;
    4440       
     
    177173        }
    178174
    179         /// <summary>
    180         /// The current ExecutionState of this PluginModel
    181         /// </summary>
    182         public PluginModelState ExecutionState{
    183             get
    184             {
    185                 return this.executionstate;
    186             }
    187             set
    188             {
    189                 this.executionstate = value;
    190             }
    191         }
    192175
    193176        /// <summary>
     
    195178        /// </summary>
    196179        /// <returns></returns>
    197         public void checkExecutable()
    198         {
    199             if(ExecutionState == PluginModelState.Undefined){
    200 
    201                 mutex.WaitOne();
    202                
    203                 bool AtLeastOneInputSet = false;
    204                 //First test if every mandatory Connector has Data
    205                 foreach (ConnectorModel connectorModel in this.InputConnectors)
     180        public void checkExecutable(ProtocolBase protocolBase)
     181        {                           
     182            bool AtLeastOneInputSet = false;
     183            //First test if every mandatory Connector has Data
     184            foreach (ConnectorModel connectorModel in this.InputConnectors)
     185            {
     186                if (connectorModel.IsMandatory && !connectorModel.HasData)
    206187                {
    207                     if (connectorModel.IsMandatory && !connectorModel.HasData)
    208                     {
    209                         mutex.ReleaseMutex();
    210                         return;
    211                     }
    212                     else if (connectorModel.HasData)
    213                     {
    214                         AtLeastOneInputSet = true;
    215                     }
    216 
    217                 }
    218 
    219                 //Next test if every connceted Connection to each Connection is not active
    220                 foreach (ConnectorModel connectorModel in this.OutputConnectors)
     188                    return;
     189                }
     190                else if (connectorModel.HasData)
    221191                {
    222                     foreach (ConnectionModel connection in connectorModel.OutputConnections)
    223                     {
    224                         if (connection.Active)
    225                         {                           
    226                             mutex.ReleaseMutex();
    227                             return;
    228                         }                       
    229                     }
    230                 }
    231 
    232                 if (AtLeastOneInputSet || this.InputConnectors.Count == 0)
     192                    AtLeastOneInputSet = true;
     193                }
     194
     195            }
     196
     197            //Next test if every connceted Connection to each Connection is not active
     198            foreach (ConnectorModel connectorModel in this.OutputConnectors)
     199            {
     200                foreach (ConnectionModel connection in connectorModel.OutputConnections)
    233201                {
    234                     ExecutionState = PluginModelState.Executable;
    235                 }
    236                 mutex.ReleaseMutex();
     202                    if (connection.Active)
     203                    {                           
     204                       return;
     205                    }                       
     206                }
     207            }
     208
     209            if (AtLeastOneInputSet || this.InputConnectors.Count == 0)
     210            {
     211                MessagePreExecution msg = new MessagePreExecution();
     212                msg.PluginModel = this;
     213                protocolBase.BroadcastMessage(msg);
    237214            }
    238215            return;
     
    261238            }
    262239        }
    263     }
    264 
    265     /// <summary>
    266     /// Execution States of a PluginModel
    267     /// </summary>
    268     public enum PluginModelState
    269     {
    270         Undefined,
    271         Executable,
    272         PreExecuting,
    273         Executing,
    274         PostExecuting,
    275         Terminated,
    276         Error
     240
     241        /// <summary>
     242        ///
     243        /// </summary>
     244        public static PluginProtocol PluginProtocol { get; set; }
    277245    }
    278246}
  • trunk/CrypPlugins/WorkspaceManager/Model/WorkspaceModel.cs

    r1581 r1590  
    191191        /// </summary>
    192192        public void resetStates()
    193         {
    194             foreach (PluginModel pluginModel in this.AllPluginModels)
    195             {
    196                 pluginModel.ExecutionState = PluginModelState.Undefined;
    197             }
     193        {           
    198194            foreach (ConnectionModel connection in this.AllConnectionModels)
    199195            {
  • trunk/CrypPlugins/WorkspaceManager/WorkspaceManager.cs

    r1570 r1590  
    342342                return;
    343343            }
    344 
    345             //for debug purposes. Later on this will be a setting of the new editor
    346             ExecutionEngine.DebugMode = true;
    347 
     344           
    348345            try
    349346            {
  • trunk/CrypPlugins/WorkspaceManager/WorkspaceManager.csproj

    r1584 r1590  
    5858  <ItemGroup Condition=" '$(Platform)' == 'x64' " />
    5959  <ItemGroup>
     60    <Reference Include="Gears4Net">
     61      <HintPath>..\..\AppReferences\x86\Gears4Net.dll</HintPath>
     62    </Reference>
    6063    <Reference Include="PresentationCore" />
    6164    <Reference Include="PresentationFramework" />
Note: See TracChangeset for help on using the changeset viewer.