aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Yang Gao <yangg@google.com>2017-11-20 16:06:24 -0800
committerGravatar GitHub <noreply@github.com>2017-11-20 16:06:24 -0800
commite295ec7cc8e6406bca5be770af75b15af218bd03 (patch)
tree9466f6e6175a1b31a08b8fc02143561d910e5b3a /src/core
parent61ea3e22a165fc7edda490ea38b2e97c0dd3e4c0 (diff)
parented49fe5510780a96bf128bc6397f0d7d5394f669 (diff)
Merge pull request #13454 from yang-g/lockfree_event
Avoid calling dtor on grpc_fd before putting it in freelist
Diffstat (limited to 'src/core')
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.cc10
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc10
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.cc10
-rw-r--r--src/core/lib/iomgr/lockfree_event.cc6
-rw-r--r--src/core/lib/iomgr/lockfree_event.h7
5 files changed, 28 insertions, 15 deletions
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index 60446f7dd5..0dda1d924c 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -263,11 +263,13 @@ static grpc_fd* fd_create(int fd, const char* name) {
if (new_fd == nullptr) {
new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd));
+ new_fd->read_closure.Init();
+ new_fd->write_closure.Init();
}
new_fd->fd = fd;
- new_fd->read_closure.Init();
- new_fd->write_closure.Init();
+ new_fd->read_closure->InitEvent();
+ new_fd->write_closure->InitEvent();
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
@@ -336,8 +338,8 @@ static void fd_orphan(grpc_exec_ctx* exec_ctx, grpc_fd* fd,
GRPC_CLOSURE_SCHED(exec_ctx, on_done, GRPC_ERROR_REF(error));
grpc_iomgr_unregister_object(&fd->iomgr_object);
- fd->read_closure.Destroy();
- fd->write_closure.Destroy();
+ fd->read_closure->DestroyEvent();
+ fd->write_closure->DestroyEvent();
gpr_mu_lock(&fd_freelist_mu);
fd->freelist_next = fd_freelist;
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index 10b84401fa..62643df697 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -286,8 +286,8 @@ static void fd_destroy(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
fd->freelist_next = fd_freelist;
fd_freelist = fd;
- fd->read_closure.Destroy();
- fd->write_closure.Destroy();
+ fd->read_closure->DestroyEvent();
+ fd->write_closure->DestroyEvent();
gpr_mu_unlock(&fd_freelist_mu);
}
@@ -340,6 +340,8 @@ static grpc_fd* fd_create(int fd, const char* name) {
if (new_fd == nullptr) {
new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd));
+ new_fd->read_closure.Init();
+ new_fd->write_closure.Init();
}
gpr_mu_init(&new_fd->pollable_mu);
@@ -347,8 +349,8 @@ static grpc_fd* fd_create(int fd, const char* name) {
new_fd->pollable_obj = nullptr;
gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
new_fd->fd = fd;
- new_fd->read_closure.Init();
- new_fd->write_closure.Init();
+ new_fd->read_closure->InitEvent();
+ new_fd->write_closure->InitEvent();
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc
index 689c0d4573..12c8483b8e 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.cc
+++ b/src/core/lib/iomgr/ev_epollsig_linux.cc
@@ -767,8 +767,8 @@ static void unref_by(grpc_fd* fd, int n) {
fd_freelist = fd;
grpc_iomgr_unregister_object(&fd->iomgr_object);
- fd->read_closure.Destroy();
- fd->write_closure.Destroy();
+ fd->read_closure->DestroyEvent();
+ fd->write_closure->DestroyEvent();
gpr_mu_unlock(&fd_freelist_mu);
} else {
@@ -819,6 +819,8 @@ static grpc_fd* fd_create(int fd, const char* name) {
if (new_fd == nullptr) {
new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd));
gpr_mu_init(&new_fd->po.mu);
+ new_fd->read_closure.Init();
+ new_fd->write_closure.Init();
}
/* Note: It is not really needed to get the new_fd->po.mu lock here. If this
@@ -833,8 +835,8 @@ static grpc_fd* fd_create(int fd, const char* name) {
gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
new_fd->fd = fd;
new_fd->orphaned = false;
- new_fd->read_closure.Init();
- new_fd->write_closure.Init();
+ new_fd->read_closure->InitEvent();
+ new_fd->write_closure->InitEvent();
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc
index d477f64ba5..f0e798e8d8 100644
--- a/src/core/lib/iomgr/lockfree_event.cc
+++ b/src/core/lib/iomgr/lockfree_event.cc
@@ -57,7 +57,9 @@ extern grpc_core::TraceFlag grpc_polling_trace;
namespace grpc_core {
-LockfreeEvent::LockfreeEvent() {
+LockfreeEvent::LockfreeEvent() { InitEvent(); }
+
+void LockfreeEvent::InitEvent() {
/* Perform an atomic store to start the state machine.
Note carefully that LockfreeEvent *MAY* be used whilst in a destroyed
@@ -67,7 +69,7 @@ LockfreeEvent::LockfreeEvent() {
gpr_atm_no_barrier_store(&state_, kClosureNotReady);
}
-LockfreeEvent::~LockfreeEvent() {
+void LockfreeEvent::DestroyEvent() {
gpr_atm curr;
do {
curr = gpr_atm_no_barrier_load(&state_);
diff --git a/src/core/lib/iomgr/lockfree_event.h b/src/core/lib/iomgr/lockfree_event.h
index c667dcd3bc..aec67a3399 100644
--- a/src/core/lib/iomgr/lockfree_event.h
+++ b/src/core/lib/iomgr/lockfree_event.h
@@ -30,11 +30,16 @@ namespace grpc_core {
class LockfreeEvent {
public:
LockfreeEvent();
- ~LockfreeEvent();
LockfreeEvent(const LockfreeEvent&) = delete;
LockfreeEvent& operator=(const LockfreeEvent&) = delete;
+ // These methods are used to initialize and destroy the internal state. These
+ // cannot be done in constructor and destructor because SetReady may be called
+ // when the event is destroyed and put in a freelist.
+ void InitEvent();
+ void DestroyEvent();
+
bool IsShutdown() const {
return (gpr_atm_no_barrier_load(&state_) & kShutdownBit) != 0;
}