/// <summary>
        /// Translate the specified service event into another
        /// <see cref="ServiceEventArgs"/> with a source set to this
        /// service.
        /// </summary>
        /// <param name="evt">
        /// The <b>ServiceEventArgs</b>.
        /// </param>
        protected virtual void TranslateEvent(ServiceEventArgs evt)
        {
            Util.IService service = Service;

            if (service == null)
            {
                // for the JOIN events, the Service property may not be set
                // until after the "real" service is started
                // (see synchronized block at the EnsureRunningService method)
                // just wait till we are out of there
                lock (this)
                {
                    service = Service;
                }
            }

            Util.IService serviceSource = evt.Service;

            // allow for post-mortem events
            ServiceEventArgs evtSafe = new ServiceEventArgs(
                service == serviceSource? this : serviceSource,
                evt.EventType);

            DispatchServiceEvent(evtSafe);
        }
 /// <summary>
 /// Block the calling thread until the wrapped <b>IService</b> event
 /// dispatcher queue is empty and all outstanding tasks have been
 /// executed.
 /// </summary>
 public virtual void DrainEvents()
 {
     Util.IService service = Service;
     if (service is Service)
     {
         ((Service)service).DrainEvents();
     }
     else if (service is RemoteService)
     {
         ((RemoteService)service).DrainEvents();
     }
 }
        /// <summary>
        /// Return the wrapped <b>IService</b>.
        /// </summary>
        /// <remarks>
        /// This method ensures that the returned <b>IService</b> is running
        /// before returning it. If the <b>IService</b> is not running and has
        /// not been explicitly stopped, the <b>IService</b> is restarted.
        /// </remarks>
        /// <param name="drain">
        /// If true and the wrapped <b>IService</b> is restarted, the calling
        /// thread will be blocked until the wrapped <b>IService</b> event
        /// dispatcher queue is empty and all outstanding tasks have been
        /// executed.
        /// </param>
        /// <returns>
        /// The running wrapped <b>IService</b>.
        /// </returns>
        public virtual Util.IService EnsureRunningService(bool drain)
        {
            Util.IService service = Service;
            if (service == null || !service.IsRunning)
            {
                // to prevent a deadlock during restart we need to obtain the lock
                // before restarting the service (see problem COH-77)
                lock (typeof(CacheFactory))
                {
                    lock (this)
                    {
                        service = Service;
                        switch (SafeServiceState)
                        {
                        case ServiceState.Initial:
                            if (service == null)
                            {
                                Service = service = RestartService();
                            }
                            else
                            {
                                StartService(service);
                            }
                            break;

                        case ServiceState.Started:
                            if (service == null || !service.IsRunning)
                            {
                                Service = null;     // release memory before restarting

                                // restart the actual service
                                CacheFactory.Log("Restarting Service: " + ServiceName,
                                                 CacheFactory.LogLevel.Info);

                                Service = service = RestartService();
                            }
                            break;

                        case ServiceState.Stopped:
                            throw new InvalidOperationException("SafeService was explicitly stopped");
                        }
                    }
                }

                if (drain)
                {
                    DrainEvents();
                }
            }

            return(service);
        }
 /// <summary>
 /// Hard-stop the controllable service.
 /// </summary>
 /// <remarks>
 /// Use <see cref="IControllable.Shutdown"/> for normal service
 /// termination. Calling this method for a service that has already
 /// stopped has no effect.
 /// </remarks>
 public virtual void Stop()
 {
     lock (this)
     {
         if (SafeServiceState != ServiceState.Stopped)
         {
             Util.IService service = Service;
             if (service != null)
             {
                 service.Stop();
             }
             Cleanup();
             SafeServiceState = ServiceState.Stopped;
         }
     }
 }
        /// <summary>
        /// Start the <see cref="IService"/>.
        /// </summary>
        /// <param name="service">
        /// The <b>IService</b> object to start.
        /// </param>
        protected virtual void StartService(Util.IService service)
        {
            service.Configure(Config);

            if (service is IService)
            {
                IService _service = (IService)service;
                _service.UserContext = UserContext;

                if (m_memberJoined != null)
                {
                    _service.MemberJoined += new MemberEventHandler(OnMemberJoined);
                }
                if (m_memberLeaving != null)
                {
                    _service.MemberLeaving += new MemberEventHandler(OnMemberLeaving);
                }
                if (m_memberLeft != null)
                {
                    _service.MemberLeft += new MemberEventHandler(OnMemberLeft);
                }
            }

            if (m_serviceStarting != null)
            {
                service.ServiceStarting += new ServiceEventHandler(OnServiceStarting);
            }
            if (m_serviceStarted != null)
            {
                service.ServiceStarted += new ServiceEventHandler(OnServiceStarted);
            }
            if (m_serviceStopping != null)
            {
                service.ServiceStopping += new ServiceEventHandler(OnServiceStopping);
            }
            if (m_serviceStopped != null)
            {
                service.ServiceStopped += new ServiceEventHandler(OnServiceStopped);
            }

            try
            {
                service.Start();
            }
            catch (Exception e)
            {
                CacheFactory.Log("Error while starting service \""
                                 + ServiceName + "\": " + e,
                                 CacheFactory.LogLevel.Error);
                try
                {
                    service.Stop();
                }
                catch (Exception e2)
                {
                    CacheFactory.Log("Failed to stop service \""
                                     + ServiceName + "\": " + e2,
                                     CacheFactory.LogLevel.Warn);
                    // eat the exception
                }

                throw;
            }
        }
 /// <summary>
 /// Provide a human-readable representation of this SafeService.
 /// </summary>
 /// <returns>
 /// A human-readable representation of this SafeService.
 /// </returns>
 public override string ToString()
 {
     Util.IService service = Service;
     return(GetType().Name + ": " + (service == null ? "STOPPED" : service.ToString()));
 }