1 #Region "Microsoft.VisualBasic::0a14747f40e78a09ce9901f39f752df5, Microsoft.VisualBasic.Core\ApplicationServices\Tools\MMFProtocol\ProcessLock.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class ProcessLock
35     
36     '         Properties: Locked
37     
38     '         Constructor: (+1 OverloadsSub New
39     '         Sub: (+2 Overloads) Dispose, ProcessLockDataArrival
40     
41     
42     ' /********************************************************************************/
43
44 #End Region
45
46 Imports System.Text.Encoding
47
48 Namespace MMFProtocol
49
50     ''' <summary>
51     ''' 进程排斥锁
52     ''' </summary>
53     ''' <remarks></remarks>
54     Public Class ProcessLock : Implements System.IDisposable
55
56         Private Const PROCESS_CHECKOUT_SIGNAL As String = "processlock-checkout-signal::[Guid('4CBC086D-179C-494E-81C6-A040667B49F0')]"
57         Private Const PROCESS_LOCKED___SIGNAL As String = "processlock-checkout-locked::[Guid('4CBC086D-179C-494E-81C6-A040667B49F0')]"
58
59         ''' <summary>
60         ''' 进程排斥锁
61         ''' </summary>
62         ''' <remarks>
63         ''' 程序中采用一个进程排斥锁是由于待日后Mono运行时环境在Linux平台中的WinForm GTK成熟后,向Linux平台迁移,
64         ''' 由于Visual Baisc/C#所编写的应用程序需要保持单个进程,则需要启用应用程序框架,而很多情况下为了优化的需求应用程序
65         ''' 无法使用应用程序框架,为了实现一次编译到处运行的目的,程序的代码不会再平台间进行修改,
66         ''' 由于Linux平台之上不能使用Win32API来保持单进程,为了保持程序对Windows/Linux/MAC三大操作系统的兼容性,故而在这里使用了一个进程排斥锁
67         ''' </remarks>
68         Dim WithEvents ProcessLock As MMFSocket
69
70         ''' <summary>
71         ''' 进程锁的排斥情况
72         ''' </summary>
73         ''' <remarks></remarks>
74         Dim f_ProcessLock As Boolean = False
75
76         Private Sub ProcessLockDataArrival(data() As Byte)
77             Dim strMessage As String = Unicode.GetString(data)   '服务器进程锁接搜到的来自进程排斥锁的新消息
78
79             If strMessage = PROCESS_CHECKOUT_SIGNAL Then    '这个是已经在运行的进程对新启动的进程的进程锁的检查的回应
80                 Call ProcessLock.SendMessage(Unicode.GetBytes(PROCESS_LOCKED___SIGNAL))
81             ElseIf strMessage = PROCESS_LOCKED___SIGNAL Then
82                 f_ProcessLock = True    '对新启动的进程执行加锁操作,杀死新启动的服务器进程
83             End If
84         End Sub
85
86         ''' <summary>
87         ''' 
88         ''' </summary>
89         ''' <param name="strHost">进程排斥锁的锁名</param>
90         ''' <remarks></remarks>
91         Sub New(strHost As String)
92             ProcessLock = New MMFSocket(strHost, AddressOf Me.ProcessLockDataArrival)
93         End Sub
94
95         ''' <summary>
96         ''' 返回当前的进程是否被加锁
97         ''' </summary>
98         ''' <returns></returns>
99         ''' <remarks></remarks>
100         Public ReadOnly Property Locked() As Boolean
101             Get
102                 'socket会首先尝试发送一个信号,然后根据有无响应来判断是否还有其他的服务器进程的运行
103                 Call ProcessLock.SendMessage(Unicode.GetBytes(PROCESS_CHECKOUT_SIGNAL))
104                 Call System.Threading.Thread.Sleep(100)       '等待响应的超时时间为100ms
105
106                 Return f_ProcessLock
107             End Get
108         End Property
109
110 #Region "IDisposable Support"
111         Private disposedValue As Boolean To detect redundant calls
112
113         ' IDisposable
114         Protected Overridable Sub Dispose(disposing As Boolean)
115             If Not Me.disposedValue Then
116                 If disposing Then
117                     ' TODO: dispose managed state (managed objects).
118                 End If
119
120                 ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
121                 ' TODO: set large fields to null.
122             End If
123             Me.disposedValue = True
124         End Sub
125
126         ' TODO: override Finalize() only if Dispose(      disposing As Boolean) above has code to free unmanaged resources.
127         'Protected Overrides Sub Finalize()
128         '    ' Do not change this code.  Put cleanup code in Dispose(      disposing As Boolean) above.
129         '    Dispose(False)
130         '    MyBase.Finalize()
131         'End Sub
132
133         ' This code added by Visual Basic to correctly implement the disposable pattern.
134         Public Sub Dispose() Implements IDisposable.Dispose
135             Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
136             Dispose(True)
137             GC.SuppressFinalize(Me)
138         End Sub
139 #End Region
140     End Class
141 End Namespace