Cumulocity Official / Mbed 2 deprecated MbedSmartRestMain Featured

Dependencies:   C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed

Fork of MbedSmartRestMain by Vincent Wochnik

Committer:
xinlei
Date:
Fri Mar 20 13:55:21 2015 +0000
Revision:
91:423177e8a401
Parent:
82:ca7430f50b2b
Child:
93:0acd11870c6a
Code refactoring to ease coupling

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xinlei 77:f6717e4eccc4 1 #include <string.h>
vwochnik 57:4af5f1bec3a6 2 #include "OperationSupport.h"
vwochnik 63:010bbbb4732a 3 #include "Aggregator.h"
vwochnik 57:4af5f1bec3a6 4 #include "ComposedRecord.h"
vwochnik 57:4af5f1bec3a6 5 #include "CharValue.h"
vwochnik 57:4af5f1bec3a6 6 #include "IntegerValue.h"
vwochnik 57:4af5f1bec3a6 7
vwochnik 59:f96be79feccd 8 CharValue aOperationStatePending("PENDING");
vwochnik 59:f96be79feccd 9 CharValue aOperationStateExecuting("EXECUTING");
vwochnik 59:f96be79feccd 10 CharValue aOperationStateSuccessful("SUCCESSFUL");
vwochnik 59:f96be79feccd 11 CharValue aOperationStateFailed("FAILED");
vwochnik 59:f96be79feccd 12
xinlei 82:ca7430f50b2b 13 OperationSupport::OperationSupport(AbstractSmartRest& client, SmartRestTemplate& tpl, long& deviceId,
xinlei 82:ca7430f50b2b 14 ConfigurationSynchronization& configurationSynchronization, DeviceIO& io,
xinlei 82:ca7430f50b2b 15 DisplayInfo& displayInfo) :
xinlei 82:ca7430f50b2b 16 _deviceId(deviceId),
vwochnik 57:4af5f1bec3a6 17 _tpl(tpl),
xinlei 82:ca7430f50b2b 18 _client(client),
xinlei 82:ca7430f50b2b 19 _executor(client, tpl, deviceId, configurationSynchronization, io, displayInfo),
vwochnik 63:010bbbb4732a 20 _thread1(OperationSupport::thread1_func, this),
vwochnik 67:c360a2b2c948 21 _thread2(OperationSupport::thread2_func, this),
vwochnik 67:c360a2b2c948 22 _thread3(OperationSupport::thread3_func, this)
vwochnik 57:4af5f1bec3a6 23 {
vwochnik 57:4af5f1bec3a6 24 _init = false;
vwochnik 67:c360a2b2c948 25 _firstRun = true;
vwochnik 57:4af5f1bec3a6 26 }
vwochnik 57:4af5f1bec3a6 27
vwochnik 57:4af5f1bec3a6 28 bool OperationSupport::init()
vwochnik 57:4af5f1bec3a6 29 {
vwochnik 57:4af5f1bec3a6 30 if (_init)
vwochnik 57:4af5f1bec3a6 31 return false;
vwochnik 57:4af5f1bec3a6 32
vwochnik 57:4af5f1bec3a6 33 // Get pending operations
vwochnik 57:4af5f1bec3a6 34 // USAGE: 110,<DEVICE/ID>
vwochnik 57:4af5f1bec3a6 35 if (!_tpl.add("10,110,GET,/devicecontrol/operations?status=PENDING&deviceId=%%&pageSize=100,,application/vnd.com.nsn.cumulocity.operationCollection+json,%%,UNSIGNED,\r\n"))
vwochnik 57:4af5f1bec3a6 36 return false;
vwochnik 57:4af5f1bec3a6 37
vwochnik 57:4af5f1bec3a6 38 // Set operation state
vwochnik 57:4af5f1bec3a6 39 // USAGE: 110,<OPERATION/ID>,<STATE>
vwochnik 58:4cc0ae5a7058 40 if (!_tpl.add("10,111,PUT,/devicecontrol/operations/%%,application/vnd.com.nsn.cumulocity.operation+json,application/vnd.com.nsn.cumulocity.operation+json,%%,UNSIGNED STRING,\"{\"\"status\"\":\"\"%%\"\"}\"\r\n"))
vwochnik 57:4af5f1bec3a6 41 return false;
vwochnik 57:4af5f1bec3a6 42
vwochnik 57:4af5f1bec3a6 43 // Get operations
vwochnik 57:4af5f1bec3a6 44 // Response: 210,<OPERATION/ID>,<STATUS>
vwochnik 57:4af5f1bec3a6 45 if (!_tpl.add("11,210,\"$.operations\",,\"$.id\",\"$.status\"\r\n"))
vwochnik 57:4af5f1bec3a6 46 return false;
vwochnik 57:4af5f1bec3a6 47
vwochnik 57:4af5f1bec3a6 48 // Get operation
vwochnik 57:4af5f1bec3a6 49 // Response: 211,<OPERATION/ID>,<STATUS>
vwochnik 57:4af5f1bec3a6 50 if (!_tpl.add("11,211,,\"$.deviceId\",\"$.id\",\"$.status\"\r\n"))
vwochnik 57:4af5f1bec3a6 51 return false;
vwochnik 63:010bbbb4732a 52
vwochnik 63:010bbbb4732a 53 if (!_executor.init())
vwochnik 63:010bbbb4732a 54 return false;
vwochnik 57:4af5f1bec3a6 55
vwochnik 57:4af5f1bec3a6 56 _init = true;
vwochnik 57:4af5f1bec3a6 57 return true;
vwochnik 57:4af5f1bec3a6 58 }
vwochnik 57:4af5f1bec3a6 59
vwochnik 57:4af5f1bec3a6 60 bool OperationSupport::run()
vwochnik 57:4af5f1bec3a6 61 {
vwochnik 67:c360a2b2c948 62 if (_firstRun) {
vwochnik 67:c360a2b2c948 63 _firstRun = false;
vwochnik 70:f489ca11f254 64 if (!requestPendingOperations())
vwochnik 70:f489ca11f254 65 return false;
vwochnik 63:010bbbb4732a 66 }
vwochnik 63:010bbbb4732a 67 return true;
vwochnik 63:010bbbb4732a 68 }
vwochnik 63:010bbbb4732a 69
vwochnik 63:010bbbb4732a 70 bool OperationSupport::requestPendingOperations()
vwochnik 63:010bbbb4732a 71 {
vwochnik 60:3c822f97fc73 72 uint8_t ret;
vwochnik 63:010bbbb4732a 73 OperationStore::Operation op;
vwochnik 60:3c822f97fc73 74
vwochnik 59:f96be79feccd 75 ComposedRecord record;
vwochnik 59:f96be79feccd 76 ParsedRecord received;
vwochnik 59:f96be79feccd 77
vwochnik 59:f96be79feccd 78 IntegerValue msgId(110);
vwochnik 59:f96be79feccd 79 IntegerValue deviceId(_deviceId);
vwochnik 59:f96be79feccd 80 if ((!record.add(msgId)) || (!record.add(deviceId)))
vwochnik 59:f96be79feccd 81 return false;
vwochnik 60:3c822f97fc73 82
vwochnik 59:f96be79feccd 83 if (_client.send(record) != SMARTREST_SUCCESS) {
vwochnik 59:f96be79feccd 84 _client.stop();
vwochnik 59:f96be79feccd 85 return false;
vwochnik 59:f96be79feccd 86 }
vwochnik 60:3c822f97fc73 87
vwochnik 60:3c822f97fc73 88 while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
vwochnik 65:a62dbef2f924 89 if (!operationFromRecord(received, op))
vwochnik 63:010bbbb4732a 90 continue;
vwochnik 70:f489ca11f254 91 _store.enqueue(op);
xinlei 91:423177e8a401 92 // _store.takePending(op);
xinlei 91:423177e8a401 93 // updateOperation(op);
xinlei 91:423177e8a401 94 // bool b = _executor.executeOperation(op);
xinlei 91:423177e8a401 95 // _store.markAsDone(op, b);
vwochnik 60:3c822f97fc73 96 }
vwochnik 59:f96be79feccd 97 _client.stop();
vwochnik 60:3c822f97fc73 98
vwochnik 60:3c822f97fc73 99 if ((ret != SMARTREST_END_OF_RESPONSE) &&
vwochnik 60:3c822f97fc73 100 (ret != SMARTREST_CONNECTION_CLOSED)) {
vwochnik 60:3c822f97fc73 101 return false;
xinlei 77:f6717e4eccc4 102 }
vwochnik 60:3c822f97fc73 103 return true;
vwochnik 57:4af5f1bec3a6 104 }
vwochnik 59:f96be79feccd 105
vwochnik 60:3c822f97fc73 106 bool OperationSupport::operationFromRecord(ParsedRecord& received, OperationStore::Operation& op)
vwochnik 59:f96be79feccd 107 {
vwochnik 59:f96be79feccd 108 const char *tmp;
vwochnik 59:f96be79feccd 109
vwochnik 59:f96be79feccd 110 if ((received.values() < 4) ||
vwochnik 59:f96be79feccd 111 (received.value(0).valueType() != VALUE_INTEGER) ||
vwochnik 70:f489ca11f254 112 //TODO: error here since streaming op does not have 210 msg id
vwochnik 70:f489ca11f254 113 // (received.value(0).integerValue() != 210) ||
vwochnik 59:f96be79feccd 114 (received.value(2).valueType() != VALUE_INTEGER) ||
vwochnik 59:f96be79feccd 115 (received.value(3).valueType() != VALUE_CHARACTER))
vwochnik 59:f96be79feccd 116 return false;
vwochnik 59:f96be79feccd 117
vwochnik 60:3c822f97fc73 118 op.identifier = received.value(2).integerValue();
vwochnik 59:f96be79feccd 119 tmp = received.value(3).characterValue();
vwochnik 59:f96be79feccd 120 if (strcmp(tmp, "EXECUTING") == 0)
vwochnik 62:86a04c5bda18 121 op.state = OPERATION_EXECUTING;
vwochnik 59:f96be79feccd 122 else if (strcmp(tmp, "SUCCESSFUL") == 0)
vwochnik 62:86a04c5bda18 123 op.state = OPERATION_SUCCESSFUL;
vwochnik 59:f96be79feccd 124 else if (strcmp(tmp, "FAILED") == 0)
vwochnik 62:86a04c5bda18 125 op.state = OPERATION_FAILED;
vwochnik 70:f489ca11f254 126 else if (strcmp(tmp, "PENDING") == 0)
vwochnik 70:f489ca11f254 127 op.state = OPERATION_PENDING;
vwochnik 59:f96be79feccd 128 else
vwochnik 70:f489ca11f254 129 return false;
xinlei 91:423177e8a401 130
vwochnik 59:f96be79feccd 131 return true;
vwochnik 59:f96be79feccd 132 }
vwochnik 59:f96be79feccd 133
vwochnik 59:f96be79feccd 134 bool OperationSupport::updateOperation(OperationStore::Operation& op)
vwochnik 59:f96be79feccd 135 {
vwochnik 59:f96be79feccd 136 ComposedRecord record;
xinlei 91:423177e8a401 137 ParsedRecord received;
vwochnik 59:f96be79feccd 138 IntegerValue msgId(111);
vwochnik 59:f96be79feccd 139 IntegerValue operationId(op.identifier);
vwochnik 59:f96be79feccd 140 if ((!record.add(msgId)) || (!record.add(operationId)) ||
vwochnik 59:f96be79feccd 141 (!record.add(operationStateValue(op))))
vwochnik 59:f96be79feccd 142 return false;
vwochnik 59:f96be79feccd 143
vwochnik 59:f96be79feccd 144 if (_client.send(record) != SMARTREST_SUCCESS) {
vwochnik 59:f96be79feccd 145 _client.stop();
vwochnik 59:f96be79feccd 146 return false;
vwochnik 59:f96be79feccd 147 }
xinlei 91:423177e8a401 148 puts("UP: sent record!");
xinlei 77:f6717e4eccc4 149 bool found = false;
xinlei 91:423177e8a401 150 while (_client.receive(received) == SMARTREST_SUCCESS) {
vwochnik 61:15719dbe8820 151 if ((received.values() == 4) &&
vwochnik 61:15719dbe8820 152 (received.value(0).valueType() == VALUE_INTEGER) &&
vwochnik 61:15719dbe8820 153 (received.value(0).integerValue() == 211) &&
vwochnik 61:15719dbe8820 154 (received.value(2).valueType() == VALUE_INTEGER) &&
vwochnik 61:15719dbe8820 155 (received.value(2).integerValue() == op.identifier)) {
vwochnik 61:15719dbe8820 156 found = true;
vwochnik 61:15719dbe8820 157 break;
vwochnik 61:15719dbe8820 158 }
vwochnik 59:f96be79feccd 159 }
xinlei 91:423177e8a401 160 puts("UP: received record!");
vwochnik 59:f96be79feccd 161 _client.stop();
vwochnik 61:15719dbe8820 162 return found;
vwochnik 59:f96be79feccd 163 }
vwochnik 59:f96be79feccd 164
vwochnik 59:f96be79feccd 165 CharValue& OperationSupport::operationStateValue(OperationStore::Operation& op)
vwochnik 59:f96be79feccd 166 {
vwochnik 59:f96be79feccd 167 switch (op.state) {
vwochnik 62:86a04c5bda18 168 case OPERATION_EXECUTING:
vwochnik 59:f96be79feccd 169 return aOperationStateExecuting;
vwochnik 62:86a04c5bda18 170 case OPERATION_SUCCESSFUL:
vwochnik 59:f96be79feccd 171 return aOperationStateSuccessful;
vwochnik 62:86a04c5bda18 172 case OPERATION_FAILED:
vwochnik 59:f96be79feccd 173 return aOperationStateFailed;
vwochnik 59:f96be79feccd 174 default:
vwochnik 59:f96be79feccd 175 return aOperationStatePending;
vwochnik 59:f96be79feccd 176 }
vwochnik 59:f96be79feccd 177 }
vwochnik 60:3c822f97fc73 178
vwochnik 63:010bbbb4732a 179 void OperationSupport::thread1()
vwochnik 60:3c822f97fc73 180 {
vwochnik 63:010bbbb4732a 181 OperationStore::Operation op;
vwochnik 63:010bbbb4732a 182 bool ret;
vwochnik 63:010bbbb4732a 183
vwochnik 63:010bbbb4732a 184 while (!_init)
vwochnik 63:010bbbb4732a 185 Thread::yield();
vwochnik 63:010bbbb4732a 186
vwochnik 63:010bbbb4732a 187 while (true) {
vwochnik 63:010bbbb4732a 188 if (!_store.takePending(op)) {
vwochnik 63:010bbbb4732a 189 Thread::yield();
vwochnik 63:010bbbb4732a 190 continue;
xinlei 91:423177e8a401 191 }
xinlei 81:4a7761914901 192 // printf("Thread 1: %l, %s, %u\r\n", op.identifier, op.descriptor, op.state);
xinlei 91:423177e8a401 193 puts("Updating op");
vwochnik 63:010bbbb4732a 194 updateOperation(op);
xinlei 91:423177e8a401 195 puts("Updated op");
vwochnik 63:010bbbb4732a 196 ret = _executor.executeOperation(op);
xinlei 91:423177e8a401 197 puts("Executed op");
vwochnik 63:010bbbb4732a 198 _store.markAsDone(op, ret);
vwochnik 63:010bbbb4732a 199 }
vwochnik 63:010bbbb4732a 200 }
vwochnik 63:010bbbb4732a 201
vwochnik 63:010bbbb4732a 202 void OperationSupport::thread2()
vwochnik 63:010bbbb4732a 203 {
vwochnik 63:010bbbb4732a 204 OperationStore::Operation op;
vwochnik 63:010bbbb4732a 205 Aggregator aggr(true);
vwochnik 63:010bbbb4732a 206
vwochnik 60:3c822f97fc73 207 while (!_init)
vwochnik 60:3c822f97fc73 208 Thread::yield();
vwochnik 60:3c822f97fc73 209
vwochnik 63:010bbbb4732a 210 while (true) {
vwochnik 63:010bbbb4732a 211 while ((!aggr.full()) && (_store.takeDone(op))) {
vwochnik 63:010bbbb4732a 212 ComposedRecord record;
vwochnik 60:3c822f97fc73 213
xinlei 81:4a7761914901 214 // printf("Thread 2: %l, %s, %u\r\n", op.identifier, op.descriptor, op.state);
vwochnik 63:010bbbb4732a 215 IntegerValue msgId(111);
vwochnik 63:010bbbb4732a 216 IntegerValue operationId(op.identifier);
vwochnik 63:010bbbb4732a 217 if ((!record.add(msgId)) || (!record.add(operationId)) ||
vwochnik 63:010bbbb4732a 218 (!record.add(operationStateValue(op))))
vwochnik 63:010bbbb4732a 219 break;
vwochnik 63:010bbbb4732a 220
vwochnik 63:010bbbb4732a 221 if (!aggr.add(record))
vwochnik 63:010bbbb4732a 222 break;
vwochnik 63:010bbbb4732a 223 }
vwochnik 63:010bbbb4732a 224
vwochnik 63:010bbbb4732a 225 if (aggr.length() == 0) {
vwochnik 63:010bbbb4732a 226 Thread::yield();
vwochnik 63:010bbbb4732a 227 continue;
vwochnik 63:010bbbb4732a 228 }
vwochnik 63:010bbbb4732a 229
xinlei 91:423177e8a401 230 puts("Sending aggr");
vwochnik 65:a62dbef2f924 231 if (_client.send(aggr) != SMARTREST_SUCCESS) { }
vwochnik 63:010bbbb4732a 232 _client.stop();
vwochnik 63:010bbbb4732a 233 aggr.clear();
vwochnik 63:010bbbb4732a 234 }
vwochnik 60:3c822f97fc73 235 }
vwochnik 60:3c822f97fc73 236
vwochnik 67:c360a2b2c948 237 void OperationSupport::thread3()
vwochnik 67:c360a2b2c948 238 {
vwochnik 70:f489ca11f254 239 char bayeuxId[33];
vwochnik 67:c360a2b2c948 240 ComposedRecord record;
vwochnik 67:c360a2b2c948 241 ParsedRecord received;
vwochnik 70:f489ca11f254 242 OperationStore::Operation op;
vwochnik 67:c360a2b2c948 243
vwochnik 67:c360a2b2c948 244 while ((!_init) || (_firstRun))
vwochnik 67:c360a2b2c948 245 Thread::yield();
vwochnik 67:c360a2b2c948 246
vwochnik 67:c360a2b2c948 247 // request Bayeux ID
vwochnik 67:c360a2b2c948 248 {
vwochnik 70:f489ca11f254 249 const char *str;
vwochnik 67:c360a2b2c948 250 IntegerValue msgId(80);
vwochnik 67:c360a2b2c948 251 if (!record.add(msgId))
vwochnik 67:c360a2b2c948 252 return;
vwochnik 67:c360a2b2c948 253
vwochnik 70:f489ca11f254 254 if ((_client.stream("/devicecontrol/notifications", record) != SMARTREST_SUCCESS) ||
vwochnik 70:f489ca11f254 255 (_client.receive(received) != SMARTREST_SUCCESS)) {
vwochnik 67:c360a2b2c948 256 _client.stop();
vwochnik 67:c360a2b2c948 257 return;
vwochnik 67:c360a2b2c948 258 }
vwochnik 70:f489ca11f254 259 _client.stop();
vwochnik 70:f489ca11f254 260
vwochnik 70:f489ca11f254 261 str = received.value(0).characterValue();
vwochnik 70:f489ca11f254 262 if ((str == NULL) || (strlen(str) > sizeof(bayeuxId)))
vwochnik 70:f489ca11f254 263 return;
vwochnik 70:f489ca11f254 264
vwochnik 70:f489ca11f254 265 strcpy(bayeuxId, str);
vwochnik 70:f489ca11f254 266 record.clear();
vwochnik 70:f489ca11f254 267 }
vwochnik 70:f489ca11f254 268
vwochnik 70:f489ca11f254 269 // set channel
vwochnik 70:f489ca11f254 270 {
xinlei 77:f6717e4eccc4 271 char chn[16];
xinlei 77:f6717e4eccc4 272 int len = 0;
vwochnik 70:f489ca11f254 273 snprintf(chn, sizeof(chn), "/%ld%n", _deviceId, &len);
vwochnik 70:f489ca11f254 274 if ((len == 0) || (len == sizeof(chn)))
vwochnik 70:f489ca11f254 275 return;
vwochnik 70:f489ca11f254 276
vwochnik 70:f489ca11f254 277 IntegerValue msgId(81);
vwochnik 70:f489ca11f254 278 CharValue bid(bayeuxId);
vwochnik 70:f489ca11f254 279 CharValue channel(chn);
vwochnik 70:f489ca11f254 280 if ((!record.add(msgId)) || (!record.add(bid)) || (!record.add(channel)))
vwochnik 70:f489ca11f254 281 return;
vwochnik 70:f489ca11f254 282
vwochnik 70:f489ca11f254 283 if ((_client.stream("/devicecontrol/notifications", record) != SMARTREST_SUCCESS) ||
vwochnik 70:f489ca11f254 284 (_client.receive(received) != SMARTREST_END_OF_RESPONSE)) {
vwochnik 67:c360a2b2c948 285 _client.stop();
vwochnik 70:f489ca11f254 286 return;
vwochnik 67:c360a2b2c948 287 }
vwochnik 70:f489ca11f254 288
vwochnik 67:c360a2b2c948 289 _client.stop();
vwochnik 70:f489ca11f254 290 record.clear();
vwochnik 70:f489ca11f254 291 }
vwochnik 70:f489ca11f254 292
vwochnik 70:f489ca11f254 293 {
vwochnik 70:f489ca11f254 294 IntegerValue msgId(83);
vwochnik 70:f489ca11f254 295 CharValue bid(bayeuxId);
vwochnik 70:f489ca11f254 296 if ((!record.add(msgId)) || (!record.add(bid)))
vwochnik 70:f489ca11f254 297 return;
vwochnik 67:c360a2b2c948 298 }
vwochnik 67:c360a2b2c948 299
vwochnik 67:c360a2b2c948 300 while (true) {
vwochnik 70:f489ca11f254 301 if (_client.stream("/devicecontrol/notifications", record) != SMARTREST_SUCCESS) {
vwochnik 70:f489ca11f254 302 _client.stop();
vwochnik 70:f489ca11f254 303 continue;
vwochnik 70:f489ca11f254 304 }
vwochnik 70:f489ca11f254 305
xinlei 91:423177e8a401 306 puts("Receiving op");
vwochnik 70:f489ca11f254 307 while (_client.receive(received) == SMARTREST_SUCCESS) {
vwochnik 70:f489ca11f254 308 if (!operationFromRecord(received, op))
vwochnik 70:f489ca11f254 309 continue;
xinlei 91:423177e8a401 310 puts("Parsed record");
xinlei 81:4a7761914901 311 // printf("Thread 3: %l, %s, %u\r\n", op.identifier, op.descriptor, op.state);
vwochnik 70:f489ca11f254 312 _store.enqueue(op);
xinlei 91:423177e8a401 313 puts("Enqueued op");
xinlei 91:423177e8a401 314 // _store.takePending(op);
xinlei 91:423177e8a401 315 // puts("Updating op");
xinlei 91:423177e8a401 316 // updateOperation(op);
xinlei 91:423177e8a401 317 // puts("Updated op");
xinlei 91:423177e8a401 318 // bool ret = _executor.executeOperation(op);
xinlei 91:423177e8a401 319 // puts("Executed op");
xinlei 91:423177e8a401 320 // _store.markAsDone(op, ret);
xinlei 91:423177e8a401 321 // puts("Marked");
vwochnik 70:f489ca11f254 322 }
xinlei 81:4a7761914901 323
vwochnik 70:f489ca11f254 324 //TODO: error checking
vwochnik 70:f489ca11f254 325 _client.stop();
vwochnik 70:f489ca11f254 326 }
vwochnik 67:c360a2b2c948 327 }
vwochnik 67:c360a2b2c948 328
vwochnik 63:010bbbb4732a 329 void OperationSupport::thread1_func(void const *arg)
vwochnik 60:3c822f97fc73 330 {
vwochnik 60:3c822f97fc73 331 OperationSupport *that;
vwochnik 60:3c822f97fc73 332 that = (OperationSupport*)arg;
vwochnik 63:010bbbb4732a 333 that->thread1();
vwochnik 60:3c822f97fc73 334 }
vwochnik 63:010bbbb4732a 335
vwochnik 63:010bbbb4732a 336 void OperationSupport::thread2_func(void const *arg)
vwochnik 63:010bbbb4732a 337 {
vwochnik 63:010bbbb4732a 338 OperationSupport *that;
vwochnik 63:010bbbb4732a 339 that = (OperationSupport*)arg;
vwochnik 63:010bbbb4732a 340 that->thread2();
vwochnik 63:010bbbb4732a 341 }
vwochnik 67:c360a2b2c948 342
vwochnik 67:c360a2b2c948 343 void OperationSupport::thread3_func(void const *arg)
vwochnik 67:c360a2b2c948 344 {
vwochnik 67:c360a2b2c948 345 OperationSupport *that;
vwochnik 67:c360a2b2c948 346 that = (OperationSupport*)arg;
vwochnik 67:c360a2b2c948 347 that->thread3();
vwochnik 67:c360a2b2c948 348 }