1 | #Region "Microsoft.VisualBasic::97968f150921e7fd613c9978de939575, Microsoft.VisualBasic.Core\ApplicationServices\Parallel\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 Overloads) Sub New |
39 | ' Sub: (+2 Overloads) Dispose, ProcessLockDataArrival |
40 | ' |
41 | ' |
42 | ' /********************************************************************************/ |
43 | |
44 | #End Region |
45 | |
46 | Imports System.Text.Encoding |
47 | Imports System.Threading |
48 | |
49 | Namespace Parallel.MMFProtocol |
50 | |
51 | ''' <summary> |
52 | ''' 进程排斥锁 |
53 | ''' </summary> |
54 | ''' <remarks></remarks> |
55 | Public Class ProcessLock : Implements IDisposable |
56 | |
57 | Private Const PROCESS_CHECKOUT_SIGNAL As String = "processlock-checkout-signal::[Guid('4CBC086D-179C-494E-81C6-A040667B49F0')]" |
58 | Private Const PROCESS_LOCKED___SIGNAL As String = "processlock-checkout-locked::[Guid('4CBC086D-179C-494E-81C6-A040667B49F0')]" |
59 | |
60 | ''' <summary> |
61 | ''' 进程排斥锁 |
62 | ''' </summary> |
63 | ''' <remarks> |
64 | ''' 程序中采用一个进程排斥锁是由于待日后Mono运行时环境在Linux平台中的WinForm GTK成熟后,向Linux平台迁移, |
65 | ''' 由于Visual Baisc/C#所编写的应用程序需要保持单个进程,则需要启用应用程序框架,而很多情况下为了优化的需求应用程序 |
66 | ''' 无法使用应用程序框架,为了实现一次编译到处运行的目的,程序的代码不会再平台间进行修改, |
67 | ''' 由于Linux平台之上不能使用Win32API来保持单进程,为了保持程序对Windows/Linux/MAC三大操作系统的兼容性,故而在这里使用了一个进程排斥锁 |
68 | ''' </remarks> |
69 | Dim WithEvents ProcessLock As MMFSocket |
70 | |
71 | ''' <summary> |
72 | ''' 进程锁的排斥情况 |
73 | ''' </summary> |
74 | ''' <remarks></remarks> |
75 | Dim f_ProcessLock As Boolean = False |
76 | |
77 | Private Sub ProcessLockDataArrival(data() As Byte) |
78 | Dim strMessage As String = Unicode.GetString(data) '服务器进程锁接搜到的来自进程排斥锁的新消息 |
79 | |
80 | If strMessage = PROCESS_CHECKOUT_SIGNAL Then '这个是已经在运行的进程对新启动的进程的进程锁的检查的回应 |
81 | Call ProcessLock.SendMessage(Unicode.GetBytes(PROCESS_LOCKED___SIGNAL)) |
82 | ElseIf strMessage = PROCESS_LOCKED___SIGNAL Then |
83 | f_ProcessLock = True '对新启动的进程执行加锁操作,杀死新启动的服务器进程 |
84 | End If |
85 | End Sub |
86 | |
87 | ''' <summary> |
88 | ''' |
89 | ''' </summary> |
90 | ''' <param name="strHost">进程排斥锁的锁名</param> |
91 | ''' <remarks></remarks> |
92 | Sub New(strHost As String) |
93 | ProcessLock = New MMFSocket(strHost, AddressOf Me.ProcessLockDataArrival) |
94 | End Sub |
95 | |
96 | ''' <summary> |
97 | ''' 返回当前的进程是否被加锁 |
98 | ''' </summary> |
99 | ''' <returns></returns> |
100 | ''' <remarks></remarks> |
101 | Public ReadOnly Property Locked() As Boolean |
102 | Get |
103 | 'socket会首先尝试发送一个信号,然后根据有无响应来判断是否还有其他的服务器进程的运行 |
104 | Call ProcessLock.SendMessage(Unicode.GetBytes(PROCESS_CHECKOUT_SIGNAL)) |
105 | Call Thread.Sleep(100) '等待响应的超时时间为100ms |
106 | |
107 | Return f_ProcessLock |
108 | End Get |
109 | End Property |
110 | |
111 | #Region "IDisposable Support" |
112 | Private disposedValue As Boolean ' To detect redundant calls |
113 | |
114 | ' IDisposable |
115 | Protected Overridable Sub Dispose(disposing As Boolean) |
116 | If Not Me.disposedValue Then |
117 | If disposing Then |
118 | ' TODO: dispose managed state (managed objects). |
119 | End If |
120 | |
121 | ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below. |
122 | ' TODO: set large fields to null. |
123 | End If |
124 | Me.disposedValue = True |
125 | End Sub |
126 | |
127 | ' TODO: override Finalize() only if Dispose( disposing As Boolean) above has code to free unmanaged resources. |
128 | 'Protected Overrides Sub Finalize() |
129 | ' ' Do not change this code. Put cleanup code in Dispose( disposing As Boolean) above. |
130 | ' Dispose(False) |
131 | ' MyBase.Finalize() |
132 | 'End Sub |
133 | |
134 | ' This code added by Visual Basic to correctly implement the disposable pattern. |
135 | Public Sub Dispose() Implements IDisposable.Dispose |
136 | ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. |
137 | Dispose(True) |
138 | GC.SuppressFinalize(Me) |
139 | End Sub |
140 | #End Region |
141 | End Class |
142 | End Namespace |