//================================================================================================================================ // NWEB //================================================================================================================================ int WEB_LISTENSOCKET(int weblisten) { //return values: //TODO int len, websocket; struct sockaddr_in cli_addr; len = sizeof(cli_addr); if ((websocket = accept(weblisten, (struct sockaddr *)&cli_addr, &len)) < 0) { libc_printf(HEADER" error system call accept\n"); return -1; } apply_block(websocket, SOCKETBLOCK); webcheck(websocket); apply_block(websocket, SOCKNONBLOCK); return 0; }
int alloc_disk_blockno(INODE *pinode, uint32_t file_blockst, uint32_t nr_block) { int i, count = 0; int level[128] = {0}; uint32_t addr[128] = {0}, stno[128] = {0}; uint32_t p = 0, q = 0; uint32_t ll[4] = {L1_ST, L2_ST, L3_ST, L4_ST}; uint32_t lp[4] = {1, L2_ST - L1_ST, L3_ST - L2_ST, L4_ST - L3_ST}; uint32_t tbuf[BLOCKSZ / sizeof(uint32_t)]; if(nr_block > 64) return 0; for(i = 0; i < 10; i++) if(i >= file_blockst && i < file_blockst + nr_block) { level[q] = 0; stno[q] = i; if(pinode->nr_block[i] == INVALID_BLOCKNO) pinode->nr_block[i] = apply_block(); addr[q++] = pinode->nr_block[i]; } for(i = 0; i < 3; i++) if(max(ll[i], file_blockst) < min(ll[i + 1], file_blockst + nr_block)) { level[q] = i + 1; stno[q] = ll[i]; if(pinode->nr_block[10 + i] == INVALID_BLOCKNO) { pinode->nr_block[10 + i] = apply_block(); clear_block(pinode->nr_block[10 + i]); } addr[q++] = pinode->nr_block[10 + i]; } if(q == 0) return 0; while(p < q) { if(level[p] > 0) { uint32_t disk_off = FILE_ST + addr[p] * BLOCKSZ; read_disk(tbuf, disk_off, sizeof(tbuf)); for(i = 0; i < sizeof(tbuf)/sizeof(uint32_t); i++) { level[q] = level[p] - 1; stno[q] = stno[p] + i * lp[level[q]]; stno[q + 1] = stno[p] + (i + 1) * lp[level[q]]; if(max(stno[q], file_blockst) < min(stno[q + 1], file_blockst + nr_block)) { if(tbuf[i] == INVALID_BLOCKNO) { tbuf[i] = apply_block(); if(level[q] > 0) clear_block(tbuf[i]); } addr[q] = tbuf[i]; q++; } } p ++; write_disk(tbuf, disk_off, sizeof(tbuf)); assert(p < 128 && q < 128); } else { assert(p < 128 && q < 128); count ++; if(count >= nr_block) { return count; } p++; } } printk("%d, %d, %d\n", file_blockst, nr_block, count); return count; }
bool database::_push_block(const signed_block& new_block) { try { uint32_t skip = get_node_properties().skip_flags; if( !(skip&skip_fork_db) ) { /// TODO: if the block is greater than the head block and before the next maitenance interval // verify that the block signer is in the current set of active witnesses. shared_ptr<fork_item> new_head = _fork_db.push_block(new_block); //If the head block from the longest chain does not build off of the current head, we need to switch forks. if( new_head->data.previous != head_block_id() ) { //If the newly pushed block is the same height as head, we get head back in new_head //Only switch forks if new_head is actually higher than head if( new_head->data.block_num() > head_block_num() ) { wlog( "Switching to fork: ${id}", ("id",new_head->data.id()) ); auto branches = _fork_db.fetch_branch_from(new_head->data.id(), head_block_id()); // pop blocks until we hit the forked block while( head_block_id() != branches.second.back()->data.previous ) pop_block(); // push all blocks on the new fork for( auto ritr = branches.first.rbegin(); ritr != branches.first.rend(); ++ritr ) { ilog( "pushing blocks from fork ${n} ${id}", ("n",(*ritr)->data.block_num())("id",(*ritr)->data.id()) ); optional<fc::exception> except; try { undo_database::session session = _undo_db.start_undo_session(); apply_block( (*ritr)->data, skip ); _block_id_to_block.store( (*ritr)->id, (*ritr)->data ); session.commit(); } catch ( const fc::exception& e ) { except = e; } if( except ) { wlog( "exception thrown while switching forks ${e}", ("e",except->to_detail_string() ) ); // remove the rest of branches.first from the fork_db, those blocks are invalid while( ritr != branches.first.rend() ) { _fork_db.remove( (*ritr)->data.id() ); ++ritr; } _fork_db.set_head( branches.second.front() ); // pop all blocks from the bad fork while( head_block_id() != branches.second.back()->data.previous ) pop_block(); // restore all blocks from the good fork for( auto ritr = branches.second.rbegin(); ritr != branches.second.rend(); ++ritr ) { auto session = _undo_db.start_undo_session(); apply_block( (*ritr)->data, skip ); _block_id_to_block.store( new_block.id(), (*ritr)->data ); session.commit(); } throw *except; } } return true; } else return false; } } try { auto session = _undo_db.start_undo_session(); apply_block(new_block, skip); _block_id_to_block.store(new_block.id(), new_block); session.commit(); } catch ( const fc::exception& e ) { elog("Failed to push new block:\n${e}", ("e", e.to_detail_string())); _fork_db.remove(new_block.id()); throw; } return false; } FC_CAPTURE_AND_RETHROW( (new_block) ) }