1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26
27 #include <kproc/extern.h>
28
29 #include <kproc/task.h>
30 #include <kproc/impl.h>
31 #include <klib/rc.h>
32
33 #define rcTask rcCmd
34
35
36 /*--------------------------------------------------------------------------
37 * KTask
38 * a deferred task abstraction
39 * specific task objects are constructed with required parameters
40 * and implement the Execute method to perform their operation
41 */
42
43
44 /* Whack
45 */
46 static
KTaskWhack(KTask * self)47 rc_t KTaskWhack ( KTask * self )
48 {
49 if ( self == NULL )
50 return RC ( rcPS, rcTask, rcDestroying, rcSelf, rcNull );
51
52 switch ( self -> vt -> v1 . maj )
53 {
54 case 1:
55 return ( * self -> vt -> v1 . destroy ) ( self );
56 }
57
58 return RC ( rcPS, rcTask, rcDestroying, rcInterface, rcBadVersion );
59 }
60
61
62 /* AddRef
63 * Release
64 */
KTaskAddRef(const KTask * self)65 LIB_EXPORT rc_t CC KTaskAddRef ( const KTask *self )
66 {
67 if ( self != NULL )
68 {
69 switch ( KRefcountAdd ( & self -> refcount, "KTask" ) )
70 {
71 case krefLimit:
72 return RC ( rcPS, rcTask, rcAttaching, rcRange, rcExcessive );
73 }
74 }
75 return 0;
76 }
77
KTaskRelease(const KTask * self)78 LIB_EXPORT rc_t CC KTaskRelease ( const KTask *self )
79 {
80 if ( self != NULL )
81 {
82 switch ( KRefcountDrop ( & self -> refcount, "KTask" ) )
83 {
84 case krefWhack:
85 return KTaskWhack ( ( KTask* ) self );
86 case krefNegative:
87 return RC ( rcPS, rcTask, rcReleasing, rcRange, rcExcessive );
88 }
89 }
90 return 0;
91 }
92
93
94 /* Execute
95 * perform deferred operation
96 */
KTaskExecute(KTask * self)97 LIB_EXPORT rc_t CC KTaskExecute ( KTask *self )
98 {
99 if ( self == NULL )
100 return RC ( rcPS, rcTask, rcExecuting, rcSelf, rcNull );
101
102 switch ( self -> vt -> v1 . maj )
103 {
104 case 1:
105 return ( * self -> vt -> v1 . execute ) ( self );
106 }
107
108 return RC ( rcPS, rcTask, rcExecuting, rcInterface, rcBadVersion );
109 }
110
111
112 /* Init
113 * initialize a newly allocated task object
114 */
KTaskInit(KTask * self,const KTask_vt * vt,const char * clsname,const char * name)115 LIB_EXPORT rc_t CC KTaskInit ( KTask *self, const KTask_vt *vt, const char *clsname, const char *name )
116 {
117 if ( self == NULL )
118 return RC ( rcFS, rcTask, rcConstructing, rcSelf, rcNull );
119 if ( vt == NULL )
120 return RC ( rcFS, rcTask, rcConstructing, rcInterface, rcNull );
121 switch ( vt -> v1 . maj )
122 {
123 case 1:
124 switch ( vt -> v1 . min )
125 {
126 /* insert new minor versions in reverse order */
127 case 0:
128 #if _DEBUGGING
129 if ( vt -> v1 . destroy == NULL ||
130 vt -> v1 . execute == NULL )
131 return RC ( rcFS, rcTask, rcConstructing, rcInterface, rcNull );
132 #endif
133 break;
134 default:
135 return RC ( rcFS, rcTask, rcConstructing, rcInterface, rcInvalid );
136 }
137 break;
138 default:
139 return RC ( rcFS, rcTask, rcConstructing, rcInterface, rcInvalid );
140 }
141
142 self -> vt = vt;
143 KRefcountInit ( & self -> refcount, 1, clsname, "init", name );
144 return 0;
145 }
146
147
148 /* Destroy
149 * destroy task
150 */
KTaskDestroy(KTask * self,const char * clsname)151 LIB_EXPORT rc_t CC KTaskDestroy ( KTask *self, const char *clsname )
152 {
153 if ( self != NULL )
154 KRefcountWhack ( & self -> refcount, clsname );
155 return 0;
156 }
157