Commit | Line | Data |
---|---|---|
059ec3d9 PH |
1 | /************************************************* |
2 | * Exim - an Internet mail transport agent * | |
3 | *************************************************/ | |
4 | ||
8d6d5106 | 5 | /* Copyright (c) University of Cambridge 1995 - 2015 */ |
059ec3d9 PH |
6 | /* See the file NOTICE for conditions of use and distribution. */ |
7 | ||
8 | /* Functions concerned with serialization. */ | |
9 | ||
10 | ||
11 | #include "exim.h" | |
12 | ||
13 | ||
14 | ||
15 | ||
16 | /************************************************* | |
17 | * Test for host or ETRN serialization * | |
18 | *************************************************/ | |
19 | ||
20 | /* This function is called when a host is listed for serialization of | |
21 | connections. It is also called when ETRN is listed for serialization. We open | |
22 | the misc database and look for a record, which implies an existing connection | |
e8ae7214 JH |
23 | or ETRN run. If increasing the count would take us past the given limit |
24 | value return FALSE. If not, bump it and return TRUE. If not found, create | |
25 | one with value 1 and return TRUE. | |
059ec3d9 PH |
26 | |
27 | Arguments: | |
28 | key string on which to serialize | |
e8ae7214 | 29 | lim parallelism limit |
059ec3d9 PH |
30 | |
31 | Returns: TRUE if OK to proceed; FALSE otherwise | |
32 | */ | |
33 | ||
34 | ||
35 | BOOL | |
e8ae7214 | 36 | enq_start(uschar *key, unsigned lim) |
059ec3d9 PH |
37 | { |
38 | dbdata_serialize *serial_record; | |
39 | dbdata_serialize new_record; | |
40 | open_db dbblock; | |
41 | open_db *dbm_file; | |
42 | ||
43 | DEBUG(D_transport) debug_printf("check serialized: %s\n", key); | |
44 | ||
45 | /* Open and lock the waiting information database. The absence of O_CREAT is | |
46 | deliberate; the dbfn_open() function - which is an Exim function - always tries | |
47 | to create if it can't open a read/write file. It expects only O_RDWR or | |
48 | O_RDONLY as its argument. */ | |
49 | ||
e8ae7214 JH |
50 | if (!(dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE))) |
51 | return FALSE; | |
059ec3d9 PH |
52 | |
53 | /* See if there is a record for this host or queue run; if there is, we cannot | |
54 | proceed with the connection unless the record is very old. */ | |
55 | ||
56 | serial_record = dbfn_read(dbm_file, key); | |
e8ae7214 | 57 | if (serial_record && time(NULL) - serial_record->time_stamp < 6*60*60) |
059ec3d9 | 58 | { |
e8ae7214 JH |
59 | if (serial_record->count >= lim) |
60 | { | |
61 | dbfn_close(dbm_file); | |
62 | DEBUG(D_transport) debug_printf("outstanding serialization record for %s\n", | |
63 | key); | |
64 | return FALSE; | |
65 | } | |
66 | new_record.count = serial_record->count + 1; | |
059ec3d9 | 67 | } |
e8ae7214 JH |
68 | else |
69 | new_record.count = 1; | |
059ec3d9 | 70 | |
e8ae7214 | 71 | /* We can proceed - insert a new record or update the old one. */ |
059ec3d9 | 72 | |
e8ae7214 JH |
73 | DEBUG(D_transport) debug_printf("write serialization record for %s val %d\n", |
74 | key, new_record.count); | |
059ec3d9 PH |
75 | dbfn_write(dbm_file, key, &new_record, (int)sizeof(dbdata_serialize)); |
76 | dbfn_close(dbm_file); | |
77 | return TRUE; | |
78 | } | |
79 | ||
80 | ||
81 | ||
82 | /************************************************* | |
83 | * Release serialization * | |
84 | *************************************************/ | |
85 | ||
86 | /* This function is called when a serialized host's connection or serialized | |
87 | ETRN queue run ends. We open the relevant database and delete its record. | |
88 | ||
89 | Arguments: | |
90 | key the serialization key | |
91 | ||
92 | Returns: nothing | |
93 | */ | |
94 | ||
95 | void | |
96 | enq_end(uschar *key) | |
97 | { | |
98 | open_db dbblock; | |
99 | open_db *dbm_file; | |
e8ae7214 | 100 | dbdata_serialize *serial_record; |
059ec3d9 PH |
101 | |
102 | DEBUG(D_transport) debug_printf("end serialized: %s\n", key); | |
103 | ||
e8ae7214 JH |
104 | if ( !(dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE)) |
105 | || !(serial_record = dbfn_read(dbm_file, key)) | |
106 | ) | |
107 | return; | |
108 | if (--serial_record->count > 0) | |
109 | { | |
110 | DEBUG(D_transport) debug_printf("write serialization record for %s val %d\n", | |
111 | key, serial_record->count); | |
112 | dbfn_write(dbm_file, key, serial_record, (int)sizeof(dbdata_serialize)); | |
113 | } | |
114 | else | |
115 | { | |
116 | DEBUG(D_transport) debug_printf("remove serialization record for %s\n", key); | |
117 | dbfn_delete(dbm_file, key); | |
118 | } | |
059ec3d9 PH |
119 | dbfn_close(dbm_file); |
120 | } | |
121 | ||
122 | /* End of enq.c */ |