1 /* 2 * Hunt - A refined core library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.concurrency.CountingCallback; 13 14 import hunt.util.Common; 15 import core.atomic; 16 import std.format; 17 18 19 /** 20 * <p> 21 * A callback wrapper that succeeds the wrapped callback when the count is 22 * reached, or on first failure. 23 * </p> 24 * <p> 25 * This callback is particularly useful when an async operation is split into 26 * multiple parts, for example when an original byte buffer that needs to be 27 * written, along with a callback, is split into multiple byte buffers, since it 28 * allows the original callback to be wrapped and notified only when the last 29 * part has been processed. 30 * </p> 31 * <p> 32 * Example: 33 * </p> 34 * 35 * <pre> 36 * void process(EndPoint endPoint, ByteBuffer buffer, Callback callback) { 37 * ByteBuffer[] buffers = split(buffer); 38 * CountCallback countCallback = new CountCallback(callback, buffers.length); 39 * endPoint.write(countCallback, buffers); 40 * } 41 * </pre> 42 */ 43 class CountingCallback : NestedCallback { 44 private shared(int) count; 45 46 this(Callback callback, int count) { 47 super(callback); 48 this.count = count; 49 } 50 51 override 52 void succeeded() { 53 // Forward success on the last success. 54 while (true) { 55 int current = count; 56 57 // Already completed ? 58 if (current == 0) 59 return; 60 61 // if (count.compareAndSet(current, current - 1)) 62 if(count == current) 63 { 64 count = current - 1; 65 if (current == 1) 66 super.succeeded(); 67 return; 68 } 69 } 70 } 71 72 override 73 void failed(Exception failure) { 74 // Forward failure on the first failure. 75 while (true) { 76 int current = count; 77 78 // Already completed ? 79 if (current == 0) 80 return; 81 82 // if (count.compareAndSet(current, 0)) 83 if(count == current) 84 { 85 count = 0; 86 super.failed(failure); 87 return; 88 } 89 } 90 } 91 92 override 93 string toString() { 94 return format("%s@%d", typeof(this).stringof, toHash()); 95 } 96 }