summaryrefslogtreecommitdiff
path: root/plugins/ExternalAPI/m_synchro.h
blob: 8ff36d1502bda3d7fbc76bdb9551a7b91e8a90aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#ifndef	__SYNCHRO_H
#define	__SYNCHRO_H

#include <windows.h>

//
//================================== OTHER DEFINITIONS ========================================
//

#define WAIT_FINISH	WAIT_OBJECT_0+1

// This structure is used to get semaphore-like synchronization:
// Includes incrementing, decrementing DWORD value and if DWORD is zero, sets event
typedef struct SynchronisedCounter
{
// Stores number value
	HANDLE Event;
	DWORD Number;

// These methods are deleted due to external plugins. Use SCGetNumber,SCInc and SCDec instead
//	DWORD GetNumber();		
//	DWORD Inc();
//	DWORD Dec();

// Yes, some code is defined here. But it is not so problematic, because it uses only Win32 API calls and Win32 structures,
	SynchronisedCounter(): Number(0)
	{
		InitializeCriticalSection(&CounterCS);
		Event=CreateEvent(NULL,FALSE,TRUE,NULL);
		SetEvent(Event);
	}

	SynchronisedCounter(HANDLE InitializedEvent): Number(0)
	{
		InitializeCriticalSection(&CounterCS);
		Event=InitializedEvent;
		SetEvent(Event);
	}

	~SynchronisedCounter()
	{
		DeleteCriticalSection(&CounterCS);
		CloseHandle(Event);
	}

//private:				//it is not private as other functions (not methods) use these members
	CRITICAL_SECTION CounterCS;
} SCOUNTER, *PSCOUNTER;

// The single-writer/multiple-reader guard 
// compound synchronization object (SO)
// Notices: Copyright (c) 1995-1997 Jeffrey Richter
// Changes: majvan, only one process implementation,
//          hFinishEV event added- signals when we do not want to use this SO anymore
typedef struct SingleWriterMultiReaderGuard
{
// This event guards access to the other objects
// managed by this data structure and also indicates 
// whether any writer threads are writing.
	HANDLE hEventNoWriter;

// This manual-reset event is signaled when
// no reader threads are reading.
	HANDLE hEventNoReaders;

// This value is used simply as a counter.
// (the count is the number of reader threads)
	HANDLE hSemNumReaders;

// The request is for not to enter critical section
// for writing or reading due to going to delete guard
	HANDLE hFinishEV;
} SWMRG, *PSWMRG;

//
//================================== FUNCTIONS DEFINITIONS ========================================
//

typedef DWORD (WINAPI *YAMN_WAITTOWRITEFCN)(PSWMRG,PSCOUNTER);
typedef void  (WINAPI *YAMN_WRITEDONEFCN)(PSWMRG,PSCOUNTER);
typedef DWORD (WINAPI *YAMN_WAITTOREADFCN)(PSWMRG);
typedef void  (WINAPI *YAMN_READDONEFCN)(PSWMRG);
typedef DWORD (WINAPI *YAMN_SCMANAGEFCN)(PSCOUNTER);

//
//================================== QUICK FUNCTION CALL DEFINITIONS ========================================
//

//These are defininitions for YAMN exported functions. Your plugin can use them.
//pYAMNFcn is global variable, it is pointer to your structure containing YAMN functions.
//It is something similar like pluginLink variable in Miranda plugin. If you use
//this name of variable, you have already defined these functions and you can use them.
//It's similar to Miranda's CreateService function.
//These functions are used to synchronize accounts. YAMN could create service for these
//functions and you could call them then e.g. CallService(MS_YAMNWAITTOWRITE,WPARAM,LPARAM),
//but I think this solution is better, because these functions are much used. It is more
//"normal" if you call function for example like:
//WaitToWrite(ActualAccount) than CallService(MS_YAMNWAITTOWRITE,ActualAccount,NULL))

//How to use YAMN functions:
//Create a structure containing pointer to functions you want to use in your plugin
//This structure can look something like this:
//
//	struct
//	{
//		YAMN_WAITTOWRITEFCN	WaitToWriteFcn;
//		YAMN_WRITEDONEFCN	WriteDoneFcn;
//	} *pYAMNFcn;
//
//then you have to fill this structure with pointers...
//you have to use YAMN service to get pointer, like this (I wrote here all functions you may need,
//you can copy to your sources only those you need):
//
//	pYAMNFcn->WaitToWriteFcn=(YAMN_WAITTOWRITEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WAITTOWRITEID,0);
//	pYAMNFcn->WriteDoneFcn=(YAMN_WRITEDONEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WRITEDONEID,0);
//	pYAMNFcn->WaitToReadFcn=(YAMN_WAITTOREADFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WAITTOREADID,0);
//	pYAMNFcn->ReadDoneFcn=(YAMN_READDONEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_READDONEID,0);
//	pYAMNFcn->SCGetNumberFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCGETNUMBERID,0);
//	pYAMNFcn->SCIncFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCINCID,0);
//	pYAMNFcn->SCDecFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCDECID,0);
//
//and in your plugin just simply use e.g.:
//
//	MsgsWriteDone(ActualAccount);		//this command leaves write access to account mails
//

#define	YAMN_WAITTOWRITEID	"YAMN/WaitToWrite"
#define	YAMN_WRITEDONEID	"YAMN/WriteDone"
#define	YAMN_WAITTOREADID	"YAMN/WaitToRead"
#define	YAMN_READDONEID		"YAMN/ReadDone"
#define	YAMN_SCGETNUMBERID	"YAMN/SCGetNumber"
#define	YAMN_SCINCID		"YAMN/SCInc"
#define	YAMN_SCDECID		"YAMN/SCDec"

#define	WaitToWrite(x)			pYAMNFcn->WaitToWriteFcn(x->AccountAccessSO,0)
#define	WaitToWriteEx(x,y)		pYAMNFcn->WaitToWriteFcn(x->AccountAccessSO,y)
#define	WriteDone(x)			pYAMNFcn->WriteDoneFcn(x->AccountAccessSO,0)
#define	WaitToRead(x)			pYAMNFcn->WaitToReadFcn(x->AccountAccessSO)
#define	WaitToReadEx(x,y)		pYAMNFcn->WaitToReadFcn(x->AccountAccessSO,y)
#define	ReadDone(x)			pYAMNFcn->ReadDoneFcn(x->AccountAccessSO)

#define	MsgsWaitToWrite(x)		pYAMNFcn->WaitToWriteFcn(x->MessagesAccessSO,0)
#define	MsgsWaitToWriteEx(x,y)		pYAMNFcn->WaitToWriteFcn(x->MessagesAccessSO,y)
#define	MsgsWriteDone(x)		pYAMNFcn->WriteDoneFcn(x->MessagesAccessSO,0)
#define	MsgsWaitToRead(x)		pYAMNFcn->WaitToReadFcn(x->MessagesAccessSO)
#define	MsgsWaitToReadEx(x)		pYAMNFcn->WaitToReadFcn(x->MessagesAccessSO,y)
#define	MsgsReadDone(x)			pYAMNFcn->ReadDoneFcn(x->MessagesAccessSO)

#define	WaitToWriteSO(x)		pYAMNFcn->WaitToWriteFcn(x,0)
#define	WaitToWriteSOEx(x,y)		pYAMNFcn->WaitToWriteFcn(x,y)
#define	WriteDoneSO(x)			pYAMNFcn->WriteDoneFcn(x,0)
#define	WaitToReadSO(x)			pYAMNFcn->WaitToReadFcn(x)
#define	WaitToReadSOEx(x,y)		pYAMNFcn->WaitToReadFcn(x,y)
#define	ReadDoneSO(x)			pYAMNFcn->ReadDoneFcn(x)

#define	SCGetNumber(x)			pYAMNFcn->SCGetNumberFcn(x)
#define	SCInc(x)			pYAMNFcn->SCIncFcn(x)
#define	SCDec(x)			pYAMNFcn->SCDecFcn(x)

#endif