|
|
1.1 root 1: #include "task.h"
2:
3: object::~object()
4: {
5: if (o_link) task_error(E_OLINK);
6: if (o_next) task_error(E_ONEXT);
7: } /* delete */
8:
9: /* note that a task can be on a chain in several places
10: */
11:
12: /* object::remember() ... */
13:
14: void
15: object::forget(register task* p)
16: /* remove all occurrences of task* p from this object's task list */
17: {
18: register olink* ll;
19: register olink* l;
20:
21: if (o_link == 0) return;
22:
23: while (o_link->l_task == p) {
24: ll = o_link;
25: o_link = ll->l_next;
26: delete ll;
27: if (o_link == 0) return;
28: };
29:
30: l = o_link;
31: while (ll = l->l_next) {
32: if (ll->l_task == p) {
33: l->l_next = ll->l_next;
34: delete ll;
35: }
36: else l = ll;
37: };
38: }
39:
40:
41: /*
42: * prepare IDLE tasks on this object for scheduling
43: * also flush the remember chain
44: */
45: void
46: object::alert()
47: {
48: register olink* l;
49: register olink* ll;
50:
51: for (l=o_link; ll = l; l=l->l_next, delete ll) {
52: register task* p = l->l_task;
53: if (p->s_state == IDLE) p->insert(0,this);
54: }
55: o_link = 0;
56: }
57:
58: /*
59: * virtual int object::pending() returns 1 if the object should be waited for.
60: * By default say yes and assume that alert() will be called somehow.
61: */
62: int
63: object::pending()
64: {
65: return 1;
66: }
67:
68: /*
69: * object::print() is a virtual function. In each derived class, derived::print()
70: * will print the derived information, then call its immediate base::print(), with
71: * second argument non-zero. The original virtual call will have the second
72: * argument 0.
73: */
74: void
75: object::print(int n, int baseClass)
76: {
77: if (!baseClass)
78: printf("Unidentified object ");
79:
80: if (n&VERBOSE) {
81: olink* l;
82: printf("this=%d, remember_chain:\n", this);
83: for (l=o_link; l; l=l->l_next) l->l_task->print(n & ~CHAIN);
84: }
85:
86: if (n&CHAIN) {
87: if (o_next) o_next->print(n);
88: }
89: printf("\n");
90: }
91:
92: int
93: object::o_type()
94: {
95: return OBJECT;
96: }
97:
98: #define macro_start static char* error_name[] = {
99: #define macro(num,name,string) string,
100: #define macro_end(last_name) };
101: task_error_messages
102: #undef macro_start
103: #undef macro
104: #undef macro_end
105:
106: static int in_error = 0;
107:
108: static void
109: print_error(int n)
110: {
111:
112: register i = (n<1 || MAXERR<n) ? 0 : n;
113:
114: printf("\n\n***** task_error(%d) %s\n",n,error_name[i]);
115:
116: if (((object*)0)->this_task()) {
117: printf("thistask: ");
118: thistask->print(VERBOSE|STACK);
119: }
120: if (sched::runchain) {
121: printf("run_chain:\n");
122: sched::runchain->print(CHAIN);
123: }
124: } /* task_error */
125:
126: int
127: object::task_error(int n)
128: {
129: if (in_error)
130: exit(in_error);
131: else
132: in_error = n;
133:
134: if (error_fct) {
135: n = (*error_fct)(n,this);
136: if (n) exit(n);
137: }
138: else {
139: print_error(n);
140: exit(n);
141: }
142: in_error = 0;
143: return 0;
144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.