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