|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
25: *
26: * IOEventSource.m - Common Event Source object class. This is an abstract
27: * class which implements a device ownership protocol, and
28: * provides a core of common services for working Event Source
29: * objects to take advantage of.
30: *
31: * HISTORY
32: * 22 May 1992 Mike Paquette at NeXT
33: * Created.
34: * 4 Aug 1993 Erik Kay at NeXT
35: * API cleanup
36: */
37:
38: #define KERNEL_PRIVATE 1
39:
40: #import <driverkit/IOEventSource.h>
41: #import <driverkit/EventInput.h>
42: #import <driverkit/eventProtocols.h>
43: #import <driverkit/generalFuncs.h>
44: #import <machkit/NXLock.h>
45: #import <bsd/dev/ev_types.h>
46:
47: #define EVSRC_PRINT 0
48: #if EVSRC_PRINT
49: #undef xpr_evsrc
50: #define xpr_evsrc(x,a,b,c,d,e) printf(x,a,b,c,d,e)
51: #endif EVSRC_PRINT
52:
53: #ifndef xpr_evsrc
54: #define xpr_evsrc(x,a,b,c,d,e)
55: #endif
56:
57: @implementation IOEventSource: IODevice
58:
59: + registerEventSource:source
60: {
61: return [[EventDriver instance] registerEventSource:source];
62: }
63:
64: /*
65: * Common EventSrc initialization
66: */
67: - init
68: {
69: [super init];
70:
71: _owner = nil;
72: _desiredOwner = nil;
73: if ( _ownerLock != nil )
74: [_ownerLock free];
75: _ownerLock = [NXLock new];
76: return self;
77: }
78:
79: - free
80: {
81: if ( _ownerLock != nil )
82: [_ownerLock free];
83: return [super free];
84: }
85:
86: /*
87: * Methods used only by subclass.
88: */
89: - owner
90: {
91: return _owner;
92: }
93:
94: - (NXLock *)ownerLock
95: {
96: return _ownerLock;
97: }
98:
99: /*
100: * Exported methods (EventSrcExported protocol).
101: */
102:
103: /*
104: * Register for event dispatch via EventTarget protocol. Returns IO_R_SUCCESS
105: * if successful, else IO_R_BUSY. The relinquishOwnership: method
106: * may be called on another client during the execution of this method.
107: */
108: - (IOReturn)becomeOwner : client
109: {
110: IOReturn rtn;
111:
112: [_ownerLock lock];
113: if(_owner != nil) {
114: xpr_evsrc("%s becomeOwner: NEGOTIATING\n",
115: [self name], 2,3,4,5);
116: if([_owner respondsTo:@selector(relinquishOwnership:)]) {
117: rtn = [_owner relinquishOwnership:self];
118: }
119: else {
120: IOLog("%s: owner does not respond to "
121: "relinquishOwnership:\n", [self name]);
122: rtn = IO_R_BUSY;
123: }
124: if(rtn == IO_R_SUCCESS) {
125: xpr_evsrc("becomeOwner: Transfer ownership\n",
126: 1,2,3,4,5);
127: _owner = client;
128: }
129: else {
130: xpr_evsrc("becomeOwner: NEGOTIATION FAILED\n",
131: 1,2,3,4,5);
132: }
133: }
134: else {
135: _owner = client;
136: rtn = IO_R_SUCCESS;
137: xpr_evsrc("%s become owner: SIMPLE CASE\n",
138: [self name], 2,3,4,5);
139: }
140: [_ownerLock unlock];
141: return rtn;
142: }
143:
144: /*
145: * Relinquish ownership. Returns IO_R_BUSY if caller is not current owner.
146: */
147: - (IOReturn)relinquishOwnership : client
148: {
149: IOReturn rtn;
150:
151: [_ownerLock lock];
152: if(_owner == client) {
153: rtn = IO_R_SUCCESS;
154: _owner = nil;
155: }
156: else {
157: rtn = IO_R_BUSY;
158: }
159: [_ownerLock unlock];
160: if((rtn == IO_R_SUCCESS) &&
161: _desiredOwner &&
162: (_desiredOwner != client)) {
163: /*
164: * Notify this potential client that it can take over.
165: * We'll most likely be called back during this method,
166: * which is why we released _ownerLock.
167: */
168: if([_desiredOwner respondsTo:@selector(canBecomeOwner:)]) {
169: xpr_evsrc("%s: notifying %s via canBecomeOwner\n",
170: [self name], [_desiredOwner name],
171: 3,4,5);
172: [_desiredOwner canBecomeOwner:self];
173: }
174: else {
175: IOLog("%s: desiredOwner does not respond to "
176: "canBecomeOwner:\n", [self name]);
177: }
178: }
179: xpr_evsrc("%s relinquishOwnership: returning %s\n",
180: [self name], [self stringFromReturn:rtn], 3,4,5);
181: return rtn;
182: }
183:
184: /*
185: * Register for intent to own upon another owner's relinquishOwnership:.
186: */
187: - (IOReturn)desireOwnership : client
188: {
189: IOReturn rtn;
190:
191: [_ownerLock lock];
192: if(_desiredOwner && (_desiredOwner != client)) {
193: rtn = IO_R_BUSY;
194: }
195: else {
196: _desiredOwner = client;
197: rtn = IO_R_SUCCESS;
198: }
199: [_ownerLock unlock];
200: xpr_evsrc("%s desireOwnership: returning %s\n",
201: [self name], [self stringFromReturn:rtn], 3,4,5);
202: return rtn;
203:
204: }
205:
206: @end
207:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.