bool CBInitNode(CBNode * self, CBDepObject database, CBNodeFlags flags, CBNodeCallbacks nodeCallbacks, CBNetworkCommunicatorCallbacks commCallbacks, CBOnMessageReceivedAction (*onMessageReceived)(CBNode *, CBPeer *, CBMessage *)){ self->flags = flags; self->database = database; self->callbacks = nodeCallbacks; self->onMessageReceived = onMessageReceived; // Initialise network communicator CBNetworkCommunicator * comm = CBGetNetworkCommunicator(self); commCallbacks.onMessageReceived = CBNodeOnMessageReceived; CBInitNetworkCommunicator(comm, CB_SERVICE_FULL_BLOCKS, commCallbacks); // Set network communicator fields. comm->flags = CB_NETWORK_COMMUNICATOR_AUTO_DISCOVERY | CB_NETWORK_COMMUNICATOR_AUTO_HANDSHAKE | CB_NETWORK_COMMUNICATOR_AUTO_PING; if (flags & CB_NODE_BOOTSTRAP) comm->flags |= CB_NETWORK_COMMUNICATOR_BOOTSTRAP; comm->version = CB_PONG_VERSION; comm->networkID = CB_PRODUCTION_NETWORK_BYTES; // ??? Add testnet support CBNetworkCommunicatorSetAlternativeMessages(comm, NULL, NULL); // Create address manager comm->addresses = CBNewNetworkAddressManager(CBNodeOnBadTime); comm->addresses->maxAddressesInBucket = 1000; comm->addresses->callbackHandler = self; // Initialise thread data self->shutDownThread = false; self->messageQueue = NULL; CBNewMutex(&self->blockAndTxMutex); CBNewMutex(&self->messageProcessMutex); CBNewCondition(&self->messageProcessWaitCond); CBNewThread(&self->messageProcessThread, CBNodeProcessMessages, self); // Initialise the storage objects if (CBNewBlockChainStorage(&self->blockChainStorage, database)) { if (CBNewAccounterStorage(&self->accounterStorage, database)){ if (CBNewNodeStorage(&self->nodeStorage, database)){ // Setup address storage if (CBNewAddressStorage(&comm->addrStorage, database)) { if (CBAddressStorageLoadAddresses(comm->addrStorage, comm->addresses)){ comm->useAddrStorage = true; return true; } }else CBLogError("Could not create the address storage object for a node"); CBFreeNodeStorage(self->nodeStorage); }else CBLogError("Could not create the node storage object for a node"); CBFreeAccounterStorage(self->accounterStorage); }else CBLogError("Could not create the accounter storage object for a node"); CBFreeBlockChainStorage(self->blockChainStorage); }else CBLogError("Could not create the block storage object for a node"); CBDestroyNetworkCommunicator(self); return false; }
bool CBNewEventLoop(CBDepObject * loopID,void (*onError)(void *),void (*onDidTimeout)(void *,void *,CBTimeOutType),void * communicator){ struct ev_loop * base = ev_loop_new(0); // Create arguments for the loop CBEventLoop * loop = malloc(sizeof(*loop)); loop->base = base; loop->onError = onError; loop->onTimeOut = onDidTimeout; loop->communicator = communicator; loop->userEvent = malloc(sizeof(*loop->userEvent)); loop->userEvent->loop = loop; ev_async_init((struct ev_async *)loop->userEvent, CBDoRun); ev_async_start(base, (struct ev_async *)loop->userEvent); // Create queue CBInitCallbackQueue(&loop->queue); // Create thread CBNewThread(&loop->loopThread, CBStartEventLoop, loop); loopID->ptr = loop; return true; }
void CBInitThreadPoolQueue(CBThreadPoolQueue * self, uint16_t numThreads, void (*process)(CBThreadPoolQueue * threadPoolQueue, void * item), void (*destroy)(void * item)){ // Create threads self->workers = malloc(sizeof(*self->workers) * numThreads); self->numThreads = numThreads; self->shutdown = false; self->process = process; self->destroy = destroy; self->finished = true; CBNewCondition(&self->finishCond); CBNewMutex(&self->finishMutex); for (uint16_t x = 0; x < numThreads; x++) { self->workers[x].queue.itemNum = 0; self->workers[x].queue.start = NULL; self->workers[x].threadPoolQueue = self; CBNewCondition(&self->workers[x].waitCond); CBNewMutex(&self->workers[x].queueMutex); CBNewThread(&self->workers[x].thread, CBThreadPoolQueueThreadLoop, self->workers + x); } }