29 using namespace basis;
45 mail_cabinet() : _waiting(0) {}
47 ~mail_cabinet() { _waiting.
reset(); }
49 mail_cabinet(mail_cabinet &
formal(to_copy)) {
53 mail_cabinet &operator =(mail_cabinet &
formal(to_copy)) {
55 "should never be called");
62 class mailbox_bank :
public int_hash<mail_cabinet>
66 ~mailbox_bank() { reset(); }
77 void add_item(
const unique_int &
id, letter *to_add);
80 bool get(
const unique_int &
id, letter * &to_receive);
87 void mailbox_bank::clean_up()
91 for (
int i = 0; i < ids.
elements(); i++) {
92 mail_cabinet *entry = find(ids[i]);
94 if (!entry->_waiting.elements()) zap(ids[i]);
98 void mailbox_bank::get_ids(
int_set &to_fill) { to_fill = ids(); }
100 void mailbox_bank::add_cabinet(
const unique_int &
id)
102 if (find(
id.raw_id()))
return;
103 mail_cabinet *to_add =
new mail_cabinet;
104 add(
id.raw_id(), to_add);
107 bool mailbox_bank::zap_cabinet(
const unique_int &
id)
109 if (!find(
id.raw_id()))
return false;
110 return zap(
id.raw_id());
113 void mailbox_bank::add_item(
const unique_int &
id, letter *to_add)
115 mail_cabinet *found = find(
id.raw_id());
118 found = find(
id.raw_id());
126 found->_waiting.append(to_add);
129 bool mailbox_bank::get(
const unique_int &
id, letter * &to_receive)
131 mail_cabinet *found = find(
id.raw_id());
132 if (!found)
return false;
134 if (!found->_waiting.elements())
return false;
135 for (
int i = 0; i < found->_waiting.elements(); i++) {
137 if (!found->_waiting.borrow(i)->ready_to_send())
continue;
139 to_receive = found->_waiting.acquire(i);
140 found->_waiting.zap(i, i);
149 : _transaction_lock(new
mutex),
150 _packages(new mailbox_bank)
157 WHACK(_transaction_lock);
163 _packages->get_ids(to_fill);
169 _packages->add_item(
id, package);
175 _packages->clean_up();
181 mail_cabinet *found = _packages->find(
id.raw_id());
185 to_return = found->_waiting.elements();
191 package = NULL_POINTER;
193 return _packages->get(
id, package);
199 bool ret = _packages->zap_cabinet(
id);
207 _packages->get_ids(ids);
208 for (
int i = 0; i < ids.
elements(); i++) {
209 mail_cabinet &mc = *_packages->find(ids[i]);
210 to_fill +=
astring(astring::SPRINTF,
"cabinet %d:", ids[i])
211 + parser_bits::platform_eol_to_chars();
212 for (
int j = 0; j < mc._waiting.elements(); j++) {
213 letter &l = *mc._waiting.borrow(j);
216 to_fill += string_manipulation::indentation(4)
217 +
astring(astring::SPRINTF,
"%4ld: ", j + 1)
218 + text + parser_bits::platform_eol_to_chars();
227 _packages->get_ids(ids);
228 for (
int i = 0; i < ids.
elements(); i++) {
229 mail_cabinet &mc = *_packages->find(ids[i]);
230 if (mc._waiting.elements() > max_letters) {
232 mc._waiting.zap(max_letters, mc._waiting.elements() - 1);
241 _packages->get_ids(ids);
242 for (
int i = 0; i < ids.
elements(); i++) {
243 mail_cabinet &mc = *_packages->find(ids[i]);
244 for (
int j = 0; j < mc._waiting.elements(); j++) {
245 letter &l = *mc._waiting.borrow(j);
246 outcome ret = to_apply(l, ids[i], data_link);
247 if ( (ret == APPLY_WHACK) || (ret == APPLY_WHACK_STOP) ) {
249 mc._waiting.zap(j, j);
251 if (ret == APPLY_WHACK_STOP)
253 }
else if (ret == APPLY_STOP) {
Provides a dynamically resizable ASCII character string.
auto_synchronizer simplifies concurrent code by automatically unlocking.
Outcomes describe the state of completion for an operation.
A virtual base class for pieces of "mail". Used by the mailbox object.
virtual void text_form(basis::base_string &fill) const =0
derived letters must print a status blurb describing their contents.
void get_ids(structures::int_set &to_fill)
stuffs the set "to_fill" with the ids of all mailboxes present.
void drop_off(const structures::unique_int &id, letter *package)
drops a "package" in the mailbox for "id".
int waiting(const structures::unique_int &id) const
returns the number of items waiting for the "id" specified, if any.
basis::outcome apply_function(letter ¤t, int uid, void *data_link)
the "apply_function" is what a user of apply() must provide.
bool pick_up(const structures::unique_int &id, letter *&package)
returns true if the mailbox for "id" had a "package" to be delivered.
bool close_out(const structures::unique_int &id)
dumps all packages stored for the "id" and shuts down its mailbox.
void clean_up()
removes any empty mailboxes from our list.
void show(basis::astring &to_fill)
provides a picture of what's waiting in the mailbox.
void limit_boxes(int max_letters)
establishes a limit on the number of letters.
void apply(apply_function *to_apply, void *data_link)
calls the "to_apply" function on possibly every letter in the mailbox.
void reset()
cleans out all of the contents.
A hash table for storing integers.
A simple object that wraps a templated set of ints.
int elements() const
Returns the number of elements in this set.
A unique identifier based on integers.
#define non_continuable_error(c, f, i)
an extra piece of information used, if available, in bounds_halt below.
#define formal(parameter)
This macro just eats what it's passed; it marks unused formal parameters.
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
A logger that sends to the console screen using the standard output device.
A dynamic container class that holds any kind of object via pointers.