1 module unde.command_line.delete_command; 2 3 import unde.global_state; 4 import unde.command_line.db; 5 6 import std.concurrency; 7 import std.stdio; 8 9 import berkeleydb.all; 10 11 package void 12 delete_command_out(T)(T cgs, string cwd, ulong cmd_id) 13 if (is (T == CMDGlobalState) || is (T == GlobalState)) 14 { 15 cgs.commit(); 16 cgs.recommit(); 17 begin: 18 Dbc cursor; 19 try 20 { 21 cursor = cgs.db_command_output.cursor(cgs.txn, 0); 22 scope(exit) cursor.close(); 23 24 Dbt key, data; 25 ulong id = 0; 26 string ks = get_key_for_command_out(command_out_key(cwd, cmd_id, 0)); 27 key = ks; 28 auto res = cursor.get(&key, &data, DB_SET_RANGE); 29 if (res == DB_NOTFOUND) 30 { 31 return; 32 } 33 34 do 35 { 36 string key_string = key.to!(string); 37 command_out_key cmd_out_key; 38 parse_key_for_command_out(key_string, cmd_out_key); 39 40 if (cmd_out_key.cwd == cwd && cmd_out_key.cmd_id == cmd_id) 41 { 42 cgs.OIT++; 43 if (cgs.is_time_to_recommit()) 44 { 45 cursor.close(); 46 cgs.recommit(); 47 cursor = cgs.db_command_output.cursor(cgs.txn, 0); 48 res = cursor.get(&key, &data, DB_SET_RANGE); 49 if (res == DB_NOTFOUND) 50 { 51 return; 52 } 53 } 54 cursor.del(); 55 } 56 else 57 { 58 break; 59 } 60 61 } while (cursor.get(&key, &data, DB_NEXT) == 0); 62 } 63 catch (DbDeadlockException exp) 64 { 65 writefln("Oops deadlock, retry"); 66 cgs.abort(); 67 cgs.recommit(); 68 goto begin; 69 } 70 } 71 72 private int 73 delete_cmd(CMDGlobalState cgs, string cwd, ulong cmd_id) 74 { 75 int result; 76 77 delete_command_out(cgs, cwd, cmd_id); 78 79 cgs.commit(); 80 cgs.recommit(); 81 begin: 82 try 83 { 84 string ks = get_key_for_command(command_key(cwd, cmd_id)); 85 Dbt key = ks; 86 auto res = cgs.db_commands.del(cgs.txn, &key); 87 } 88 catch (DbDeadlockException exp) 89 { 90 writefln("Oops deadlock, retry"); 91 cgs.abort(); 92 cgs.recommit(); 93 goto begin; 94 } 95 96 return result; 97 } 98 99 private void 100 command(string cwd, ulong cmd_id, Tid tid) 101 { 102 CMDGlobalState cgs = new CMDGlobalState(); 103 try { 104 scope(exit) 105 { 106 destroy(cgs); 107 } 108 delete_cmd(cgs, cwd, cmd_id); 109 cgs.commit(); 110 } catch (shared(Throwable) exc) { 111 send(tid, exc); 112 } 113 114 writefln("Finish delete command %s ID=%d", cwd, cmd_id); 115 send(tid, thisTid); 116 } 117 118 public int 119 delete_command(GlobalState gs, string cwd, ulong cmd_id) 120 { 121 writefln("Start delete command %s ID=%d", cwd, cmd_id); 122 auto tid = spawn(&.command, cwd, cmd_id, thisTid); 123 gs.delete_commands[tid] = cmd_id; 124 return 0; 125 } 126