SheafSystem  0.0.0.0
read_write_monitor_handle.cc
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
18 // Implementation for class read_write_monitor_handle
19 
20 #include "SheafSystem/read_write_monitor_handle.h"
21 #include "SheafSystem/assert_contract.h"
22 #include "SheafSystem/poset_state.h"
23 #include "SheafSystem/read_write_monitor.h"
24 
25 #undef DEBUG
26 
27 #ifdef DEBUG
28 #include "SheafSystem/poset_state_handle.h"
29 #endif
30 
32 bool
34 is_ancestor_of(const any* xother) const
35 {
36  bool result;
37 
38  // Preconditions:
39 
40  // Body:
41 
42  result = dynamic_cast<const read_write_monitor_handle*>(xother) != 0;
43 
44  // Postconditions:
45 
46  // Exit
47 
48  return result;
49 }
50 
51 
55 clone() const
56 {
57  read_write_monitor_handle* result = 0;
58 
59  // Preconditions:
60 
61  // Body:
62 
63  // Does nothing, since this class is abstract;
64  // just redefines the postcondition.
65 
66  // Should never be called.
67 
68  not_implemented();
69 
70  // Postconditions:
71 
72  ensure(result != 0);
73  ensure(!result->is_attached());
74 
75  // Exit
76 
77  return result;
78 }
79 
83 {
84  // Preconditions:
85 
86 
87  // Body:
88 
89  // Nothing to do.
90 
91  // Postconditions:
92 
93 
94  // Exit:
95 
96  return;
97 }
98 
99 // ===========================================================
100 // GLOBAL ACCESS CONTROL FACET
101 // ===========================================================
102 
103 // PUBLIC MEMBER FUNCTIONS
104 
105 bool
108 {
110 }
111 
112 // void
113 // sheaf::read_write_monitor_handle::
114 // disable_access_control()
115 // {
116 // // cout << endl << "Entering read_write_monitor_handle::disable_access_control." << endl;
117 
118 // // Preconditions:
119 
120 // // Body:
121 
122 // read_write_monitor::disable_access_control();
123 
124 // // Postconditions:
125 
126 // ensure(access_control_disabled());
127 
128 // // Exit:
129 
130 // // cout << "Leaving read_write_monitor_handle::disable_access_control." << endl;
131 // return;
132 // }
133 
134 void
137 {
138  // cout << endl << "Entering read_write_monitor_handle::enable_access_control." << endl;
139 
140  // Preconditions:
141 
142  // Body:
143 
145 
146  // Postconditions:
147 
148  ensure(!access_control_disabled());
149 
150  // Exit:
151 
152  // cout << "Leaving read_write_monitor_handle::enable_access_control." << endl;
153  return;
154 }
155 
156 // PROTECTED MEMBER FUNCTIONS
157 
158 // PRIVATE MEMBER FUNCTIONS
159 
160 
161 // HANDLE INTERFACE
162 
164 bool
166 is_attached() const
167 {
168  bool result;
169 
170  // Preconditions:
171 
172  // Body:
173 
174  result = (state_obj() != 0);
175 
176  // Postconditions:
177 
178  // Exit
179 
180  return result;
181 }
182 
183 
184 // ACCESS CONTROL INTERFACE
185 
186 bool
189 {
190  bool result;
191 
192  // Preconditions:
193 
194  // None
195 
196  // Body:
197 
198  // Meaning of is_attached is stricter in descendants, we don't want that
199  // so use scope operator to make sure we get the right definition
200 
202 
203  // Postconditions:
204 
205  ensure(!is_attached() ? !result : true);
206  ensure((is_attached() && access_control_disabled()) ? !result : true);
207 
208  // Exit:
209 
210  return result;
211 }
212 
213 bool
216 {
217  bool result;
218 
219  // Preconditions:
220 
221  // None
222 
223  // Body:
224 
225  // Meaning of is_attached is stricter in descendants, we don't want that
226  // so use scope operator to make sure we get the right definition
227 
229 
230  // Postconditions:
231 
232  ensure(!is_attached() ? !result : true);
233  ensure((is_attached() && access_control_disabled()) ? result : true);
234  ensure((is_attached() && !access_control_disabled()) ? result == !state_is_read_only_accessible() : true);
235 
236  // Exit:
237 
238  return result;
239 }
240 
241 
242 bool
245 {
246  bool result;
247 
248  // Preconditions:
249 
250  // None
251 
252  // Body:
253 
254  // Meaning of is_attached is stricter in descendants, we don't want that
255  // so use scope operator to make sure we get the right definition
256 
258 
259  // Postconditions:
260 
261  ensure(!is_attached() ? !result : true);
262  ensure((is_attached() && access_control_disabled()) ? result : true);
263  ensure((is_attached() && !access_control_disabled()) ?
265  true);
266 
267  // None
268 
269  // Exit:
270 
271  return result;
272 }
273 
274 bool
277 {
278  bool result;
279 
280  // Preconditions:
281 
282  // None
283 
284  // Body:
285 
286  // Meaning of is_attached is stricter in descendants, we don't want that
287  // so use scope operator to make sure we get the right definition
288 
290 
291 
292  // Postconditions:
293 
294  ensure(!is_attached() ? !result : true);
295  ensure((is_attached() && access_control_disabled()) ? result : true);
296  ensure((is_attached() && !access_control_disabled()) ? result == !state_is_read_accessible() : true);
297 
298  // None
299 
300  // Exit:
301 
302  return result;
303 }
304 
305 
307 bool
309 state_is_auto_read_accessible(bool xauto_access) const
310 {
311  bool result;
312 
313  // Preconditions:
314 
315  // Body:
316 
317  result = (xauto_access ? is_attached() : state_is_read_accessible());
318 
319  // Postconditions:
320 
321  ensure(!is_attached() ? !result : true);
322  ensure(result == (xauto_access ? is_attached() : state_is_read_accessible()));
323  ensure((is_attached() && access_control_disabled()) ? result : true);
324 
325  // Exit:
326 
327  return result;
328 }
329 
330 
331 bool
334 {
335  bool result;
336 
337  // Preconditions:
338 
339  // None
340 
341  // Body:
342 
343  // Meaning of is_attached is stricter in descendants, we don't want that
344  // so use scope operator to make sure we get the right definition
345 
347 
348  // Postconditions:
349 
350  ensure(!is_attached() ? !result : true);
351  ensure((is_attached() && access_control_disabled()) ? result : true);
352 
353  // Exit:
354 
355  return result;
356 }
357 
358 bool
361 {
362  bool result;
363 
364  // Preconditions:
365 
366  // None
367 
368  // Body:
369 
370 
372 
373  // Postconditions:
374 
375  ensure(!is_attached() ? !result : true);
376  ensure((is_attached() && access_control_disabled()) ? result : true);
377  ensure((is_attached() && !access_control_disabled()) ? (result == !state_is_read_write_accessible()) : true);
378 
379  // Exit:
380 
381  return result;
382 }
383 
385 bool
387 state_is_auto_read_write_accessible(bool xauto_access) const
388 {
389  bool result;
390 
391  // Preconditions:
392 
393  // Body:
394 
395  result = (xauto_access ? is_attached() : state_is_read_write_accessible());
396 
397  // Postconditions:
398 
399  ensure(!is_attached() ? !result : true);
400  ensure(result == (xauto_access ? is_attached() : state_is_read_write_accessible()));
401  ensure((is_attached() && access_control_disabled()) ? result : true);
402 
403  // Exit:
404 
405  return result;
406 }
407 
408 
409 
411 int
414 {
415  int result;
416 
417  // Preconditions:
418 
419  require(is_attached());
420 
421  // None
422 
423  // Body:
424 
425  result = state_obj()->access_request_depth();
426 
427  // Postconditions:
428 
429  ensure(result >= 0);
430 
431  // Exit:
432 
433  return result;
434 }
435 
436 
438 void
441 {
442  // Preconditions:
443 
444  require(is_attached());
445 
446  // Body:
447 
448  int old_access_request_depth = state_obj()->access_request_depth();
449 
451 
452 #ifdef DEBUG
453 
454  poset_state_handle* lpsh = dynamic_cast<poset_state_handle*>(this);
455  if(lpsh != 0)
456  {
457  int lindex = lpsh->index();
458  cout << "read locking poset " << lindex << " level " << state_obj()->access_request_depth() << endl;
459  }
460 
461  abstract_poset_member* lapm = dynamic_cast<abstract_poset_member*>(this);
462  if(lapm != 0)
463  {
464  int lindex = lapm->host()->index();
465  cout << "read locking poset by mbr " << lindex << " level " << state_obj()->access_request_depth() << endl;
466  }
467 
468 #endif
469 
470  // Postconditions:
471 
472  ensure(state_is_read_accessible());
473  ensure(access_request_depth() == old_access_request_depth + 1);
474 
475  // Exit:
476 
477  return;
478 }
479 
480 
482 void
484 get_read_write_access(bool xrelease_read_only_access)
485 {
486 
487  // Preconditions:
488 
489  require(is_attached());
490  require(!xrelease_read_only_access ? state_is_not_read_only_accessible() : true);
491 
492 
493  // Body:
494 
495  int old_access_request_depth = state_obj()->access_request_depth();
496 
497  state_obj()->get_read_write_access(xrelease_read_only_access);
498 
499 #ifdef DEBUG
500 
501  poset_state_handle* lpsh = dynamic_cast<poset_state_handle*>(this);
502  if(lpsh != 0)
503  {
504  int lindex = lpsh->index();
505  cout << "write locking poset " << lindex << " level " << state_obj()->access_request_depth() << endl;
506  }
507 
508  abstract_poset_member* lapm = dynamic_cast<abstract_poset_member*>(this);
509  if(lapm != 0)
510  {
511  int lindex = lapm->host()->index();
512  cout << "write locking poset by mbr " << lindex << " level " << state_obj()->access_request_depth() << endl;
513  }
514 
515 #endif
516 
517  // Postconditions:
518 
520  ensure(access_request_depth() == old_access_request_depth + 1);
521 
522  // Exit:
523 
524  return;
525 }
526 
527 
529 void
531 release_access(bool xall) const
532 {
533  // Preconditions:
534 
535  require(state_is_read_accessible());
536 
537  // Body:
538 
539  int old_access_request_depth = state_obj()->access_request_depth();
540 
541  state_obj()->release_access(xall);
542 
543 #ifdef DEBUG
544 
545  poset_state_handle* lpsh = dynamic_cast<poset_state_handle*>(this);
546  if(lpsh != 0)
547  {
548  int lindex = lpsh->index();
549  cout << "releasing poset " << lindex << " level " << state_obj()->access_request_depth() << endl;
550  }
551 
552  abstract_poset_member* lapm = dynamic_cast<abstract_poset_member*>(this);
553  if(lapm != 0)
554  {
555  int lindex = lapm->host()->index();
556  cout << "releasing poset by mbr " << lindex << " level " << state_obj()->access_request_depth() << endl;
557  }
558 
559 #endif
560 
561  // Postconditions:
562 
563  ensure(!xall ? access_request_depth() == old_access_request_depth - 1 :
564  access_request_depth() == 0);
565  ensure(access_request_depth() == 0 ? state_is_not_read_accessible() : true);
566 
567  // Exit:
568 
569  return;
570 }
571 
572 // MODE LOCK CONTROL INTERFACE
573 
575 bool
578 {
579  bool result;
580 
581  // Preconditions:
582 
583  // None
584 
585  // Body:
586 
587  // Meaning of is_attached is stricter in descendants, we don't want that
588  // so use scope operator to make sure we get the right definition
589 
591 
592  // Postconditions:
593 
594  // None
595 
596  // Exit:
597 
598  return result;
599 }
600 
601 
603 int
606 {
607  int result;
608 
609  // Preconditions:
610 
611  require(is_attached());
612 
613  // None
614 
615  // Body:
616 
617  result = state_obj()->mode_lock_ct();
618 
619  // Postconditions:
620 
621  ensure(result >= 0);
622 
623  // Exit:
624 
625  return result;
626 }
627 
628 
629 
630 
632 void
635 {
636  // Preconditions:
637 
638  require(is_attached());
639 
640  // Body:
641 
643 
644  // Postconditions:
645 
646  ensure(state_is_mode_locked());
647 
648  // Exit:
649 
650  return;
651 }
652 
653 
655 void
658 {
659  // Preconditions:
660 
661  require(state_is_mode_locked());
662 
663  // Body:
664 
666 
667  // Postconditions:
668 
669 
670  // Exit:
671 
672  return;
673 }
674 
675 
677 bool
680 {
681  bool result;
682 
683  // Preconditions:
684 
685  require(is_attached());
686 
687  // Body:
688 
689  result = state_obj()->is_modified();
690 
691  // Postconditions:
692 
693  // Exit
694 
695  return result;
696 }
697 
698 
700 void
703 {
704 
705  // Preconditions:
706 
707  require(is_attached());
708 
709  // Body:
710 
712 
713  // Postconditions:
714 
715  ensure(!state_is_modified());
716 
717  // Exit
718 
719  return;
720 }
poset_state_handle * host() const
The poset which this is a handle to a component of.
bool state_is_auto_read_write_accessible(bool xauto_access) const
True if state is auto accessible for read and write, that is, if the state is already accessible for ...
bool state_is_not_read_only_accessible() const
True if this is attached and the state is not accessible for read only access.
const scoped_index & index() const
The member index of this poset within the namespace host()
bool state_is_read_accessible() const
True if this is attached and if the state is accessible for read or access control is disabled...
bool is_not_read_only_accessible() const
True if this thread does not have read-only access.
bool state_is_auto_read_accessible(bool xauto_access) const
True if the state is auto accessible for read, that is, if the state is already accessible for read o...
static void enable_access_control()
Enables access control. Synonym for read_write_monitor::enable_access_control(). Should only be invok...
A handle for a hidden read_write_monitor state.
A client handle for a general, abstract partially order set.
virtual void get_read_access() const
Get read access to the state associated with this.
void get_read_access() const
Get read access to the state associated with this.
virtual read_write_monitor_handle * clone() const
Make a new, unattached handle of the same type as this.
void clear_is_modified()
Makes is_modified() false.
bool state_is_not_read_write_accessible() const
True if state is attached and if not accessible for read and write or access control is disabled...
bool is_read_write_accessible() const
True if this thread has read-write access or if access control is not enabled.
virtual bool is_ancestor_of(const any *xother) const
True if other conforms to current.
void get_read_write_access(bool xrelease_read_only_access=false)
Get read write access to the state associated with this. If release_read_only_access is requested...
virtual read_write_monitor * state_obj() const =0
State object for this handle.
Abstract base class with useful features for all objects.
Definition: any.h:39
void clear_state_is_modified()
Sets the state_is_modified floag to false.
virtual void release_access(bool xall=false) const
Release access. If xall is true, release all levels of access. Otherwise, release one level of access...
bool state_is_read_write_accessible() const
True if this is attached and if the state is accessible for read and write or access control is disab...
int access_request_depth() const
Number of times access has been granted without a corresponding release.
void release_access(bool xall=false) const
Release access. If xall is true, release all levels of access. Otherwise, release one level of access...
bool state_is_modified() const
True if write access has been granted and released since the last call to clear_state_is_modified().
bool is_read_only_accessible() const
True if this thread has read-only access.
virtual void get_read_write_access(bool xrelease_read_only_access=false)
Get read write access to the state associated with this. If release_read_only_access is requested...
virtual bool is_attached() const
True if this handle has a state associated with it.
bool is_not_read_accessible() const
True if this thread has neither read-only or read-write access or if access control is disabled...
static bool access_control_disabled()
True if access control mechanism is disabled. Default value is enabled (false) and access is controll...
int access_request_depth() const
The number of times access has been requested and granted without being released. ...
bool is_not_read_write_accessible() const
True if this thread does not have read-write access or if access control is not enabled.
static bool access_control_disabled()
True if access control mechanism is disabled. Default value is enabled (false) and access is controll...
bool is_modified() const
True if any client has had read-write access to this object since the last call to clear_is_modified(...
An abstract client handle for a member of a poset.
bool is_read_accessible() const
True if this thread has read-only or read-write access.
virtual ~read_write_monitor_handle()
Descturctor.
static void enable_access_control()
Enables access control. Should only be invoked once at beginning of a program, before any other Sheaf...
bool state_is_not_read_accessible() const
True if this is attached and if the state is accessible for read or if access control is disabled...
bool state_is_read_only_accessible() const
True if this is attached and the state is accessible for read access but not for write.