2020-08-28 14:02:51 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2020 The Netty Project
|
|
|
|
*
|
|
|
|
* The Netty Project licenses this file to you under the Apache License,
|
|
|
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
|
|
* with the License. You may obtain a copy of the License at:
|
|
|
|
*
|
2020-10-28 14:38:14 +01:00
|
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
2020-08-28 14:02:51 +02:00
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
|
|
|
*/
|
2020-11-17 15:38:11 +01:00
|
|
|
package io.netty.buffer.api;
|
2020-07-24 19:38:48 +02:00
|
|
|
|
2020-08-24 16:03:02 +02:00
|
|
|
/**
|
|
|
|
* An Rc is a reference counted, thread-confined, resource of sorts. Because these resources are thread-confined, the
|
|
|
|
* reference counting is NOT atomic. An Rc can only be accessed by one thread at a time - the owner thread that the
|
|
|
|
* resource is confined to.
|
|
|
|
* <p>
|
|
|
|
* When the last reference is closed (accounted for using {@link AutoCloseable} and try-with-resources statements,
|
|
|
|
* ideally), then the resource is desposed of, or released, or returned to the pool it came from. The precise action is
|
|
|
|
* implemented by the {@link Drop} instance given as an argument to the Rc constructor.
|
|
|
|
*
|
2020-08-28 12:17:41 +02:00
|
|
|
* @param <I> The concrete subtype.
|
2020-08-24 16:03:02 +02:00
|
|
|
*/
|
Introduce Deref abstraction
Motivation:
Sometimes, we wish to operate on both buffers and anything that can produce a buffer.
For instance, when making a composite buffer, we could compose either buffers or sends.
Modification:
Introduce a Deref interface, which is extended by both Rc and Send.
A Deref can be used to acquire an Rc instance, and in doing so will also acquire a reference to the Rc.
That is, dereferencing increases the reference count.
For Rc itself, this just delegates to Rc.acquire, while for Send it delegates to Send.receive, and can only be called once.
The Allocator.compose method has been changed to take Derefs.
This allows us to compose either Bufs or Sends of bufs.
Or a mix.
Extra care and caution has been added to the code, to make sure the reference counts are managed correctly when composing buffers, now that it's a more complicated operation.
A handful of convenience methods for working with Sends have also been added to the Send interface.
Result:
We can now build a composite buffer out of sends of buffers.
2021-02-11 14:08:22 +01:00
|
|
|
public interface Rc<I extends Rc<I>> extends AutoCloseable, Deref<I> {
|
2020-08-24 16:03:02 +02:00
|
|
|
/**
|
|
|
|
* Increment the reference count.
|
|
|
|
* <p>
|
2020-10-30 14:21:20 +01:00
|
|
|
* Note, this method is not thread-safe because reference counted objects are meant to thread-confined.
|
2020-08-24 16:03:02 +02:00
|
|
|
*
|
|
|
|
* @return This Rc instance.
|
|
|
|
*/
|
2020-08-28 12:17:41 +02:00
|
|
|
I acquire();
|
2020-07-24 19:38:48 +02:00
|
|
|
|
Introduce Deref abstraction
Motivation:
Sometimes, we wish to operate on both buffers and anything that can produce a buffer.
For instance, when making a composite buffer, we could compose either buffers or sends.
Modification:
Introduce a Deref interface, which is extended by both Rc and Send.
A Deref can be used to acquire an Rc instance, and in doing so will also acquire a reference to the Rc.
That is, dereferencing increases the reference count.
For Rc itself, this just delegates to Rc.acquire, while for Send it delegates to Send.receive, and can only be called once.
The Allocator.compose method has been changed to take Derefs.
This allows us to compose either Bufs or Sends of bufs.
Or a mix.
Extra care and caution has been added to the code, to make sure the reference counts are managed correctly when composing buffers, now that it's a more complicated operation.
A handful of convenience methods for working with Sends have also been added to the Send interface.
Result:
We can now build a composite buffer out of sends of buffers.
2021-02-11 14:08:22 +01:00
|
|
|
@Override
|
|
|
|
default I get() {
|
|
|
|
return acquire();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
default boolean isInstanceOf(Class<?> cls) {
|
|
|
|
return cls.isInstance(this);
|
|
|
|
}
|
|
|
|
|
2020-08-24 16:03:02 +02:00
|
|
|
/**
|
|
|
|
* Decrement the reference count, and despose of the resource if the last reference is closed.
|
|
|
|
* <p>
|
2020-10-30 14:21:20 +01:00
|
|
|
* Note, this method is not thread-safe because reference counted objects are meant to be thread-confined.
|
2020-08-24 16:03:02 +02:00
|
|
|
*
|
|
|
|
* @throws IllegalStateException If this Rc has already been closed.
|
|
|
|
*/
|
2020-07-24 19:38:48 +02:00
|
|
|
@Override
|
2020-08-24 16:34:32 +02:00
|
|
|
void close();
|
2020-07-24 19:38:48 +02:00
|
|
|
|
|
|
|
/**
|
2020-10-30 14:21:20 +01:00
|
|
|
* Send this reference counted object instance to another Thread, transferring the ownership to the recipient.
|
2020-08-24 16:03:02 +02:00
|
|
|
* <p>
|
2020-11-16 18:00:32 +01:00
|
|
|
* Note that the object must be {@linkplain #isOwned() owned}, and cannot have any outstanding borrows,
|
2020-10-30 14:21:20 +01:00
|
|
|
* when it's being sent.
|
2020-11-16 18:00:32 +01:00
|
|
|
* That is, all previous acquires must have been closed, and {@link #isOwned()} must return {@code true}.
|
2020-10-30 14:21:20 +01:00
|
|
|
* <p>
|
|
|
|
* This instance immediately becomes inaccessible, and all attempts at accessing this reference counted object
|
|
|
|
* will throw. Calling {@link #close()} will have no effect, so this method is safe to call within a
|
|
|
|
* try-with-resources statement.
|
2020-07-24 19:38:48 +02:00
|
|
|
*/
|
2020-08-28 12:17:41 +02:00
|
|
|
Send<I> send();
|
2020-10-30 14:21:20 +01:00
|
|
|
|
|
|
|
/**
|
2020-11-16 18:00:32 +01:00
|
|
|
* Check that this reference counted object is owned.
|
2020-10-30 14:21:20 +01:00
|
|
|
* <p>
|
2020-11-16 18:00:32 +01:00
|
|
|
* To be owned, the object must have no outstanding acquires, and no other implementation defined restrictions.
|
2020-10-30 14:21:20 +01:00
|
|
|
*
|
|
|
|
* @return {@code true} if this object can be {@linkplain #send() sent},
|
|
|
|
* or {@code false} if calling {@link #send()} would throw an exception.
|
|
|
|
*/
|
2020-11-16 18:00:32 +01:00
|
|
|
boolean isOwned();
|
2020-11-12 14:55:42 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Count the number of borrows of this object.
|
2020-11-16 18:00:32 +01:00
|
|
|
* Note that even if the number of borrows is {@code 0}, this object might not be {@linkplain #isOwned() owned}
|
|
|
|
* because there could be other restrictions involved in ownership.
|
2020-11-12 14:55:42 +01:00
|
|
|
*
|
2020-11-16 18:00:32 +01:00
|
|
|
* @return The number of borrows, if any, of this object.
|
2020-11-12 14:55:42 +01:00
|
|
|
*/
|
|
|
|
int countBorrows();
|
2021-02-17 13:54:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if this object is accessible.
|
|
|
|
*
|
|
|
|
* @return {@code true} if this object is still valid and can be accessed,
|
|
|
|
* otherwise {@code false} if, for instance, this object has been dropped/deallocated,
|
|
|
|
* or been {@linkplain #send() sent} elsewhere.
|
|
|
|
*/
|
|
|
|
boolean isAccessible();
|
2020-07-24 19:38:48 +02:00
|
|
|
}
|