Skip to content

bpo-30980: Fix double close in asyncore.file_wrapper#2789

Merged
vstinner merged 3 commits into
python:masterfrom
nirs:double-close
Jul 24, 2017
Merged

bpo-30980: Fix double close in asyncore.file_wrapper#2789
vstinner merged 3 commits into
python:masterfrom
nirs:double-close

Conversation

@nirs
Copy link
Copy Markdown
Contributor

@nirs nirs commented Jul 20, 2017

test_close_twice was not considering the fact that file_wrapper is
duping the file descriptor. Closing the original descriptor left the
duped one open, hiding the fact that close protection is not effective.

test_close_twice was not considering the fact that file_wrapper is
duping the file descriptor. Closing the original descriptor left the
duped one open, hiding the fact that close protection is not effective.
@mention-bot
Copy link
Copy Markdown

@nirs, thanks for your PR! By analyzing the history of the files in this pull request, we identified @giampaolo, @ezio-melotti and @pitrou to be potential reviewers.

@nirs
Copy link
Copy Markdown
Contributor Author

nirs commented Jul 20, 2017

@Haypo, please review.

Invalidated self.fd before closing, handling correctly the case when
os.close raises.
@vstinner
Copy link
Copy Markdown
Member

I don't understand this change, can you please elaborate? It make the test failing.

======================================================================
FAIL: test_close_twice (test.test_asyncore.FileWrapperTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/haypo/prog/python/master/Lib/test/test_asyncore.py", line 439, in test_close_twice
    self.assertEqual(f.fd, -1)
AssertionError: 4 != -1

Is it supposed to fix a bug?

@nirs nirs changed the title bpo-30980: Fix close test to fail bpo-30980: Fix double close Jul 20, 2017
@nirs nirs changed the title bpo-30980: Fix double close bpo-30980: Fix double close in asyncore.file_wrapper Jul 20, 2017
@nirs
Copy link
Copy Markdown
Contributor Author

nirs commented Jul 20, 2017

@Haypo the first patch added a failing test to demonstrate the issue, the second patch fixes it.

@vstinner
Copy link
Copy Markdown
Member

The test now leaks a file descriptor:

haypo@selma$ ./python -m test -R 3:3 test_asyncore -m test_close_twice
Run tests sequentially
0:00:00 load avg: 0.37 [1/1] test_asyncore
beginning 6 repetitions
123456
......
test_asyncore leaked [1, 1, 1] file descriptors, sum=3
test_asyncore failed

1 test failed:
    test_asyncore

Total duration: 189 ms
Tests result: FAILURE

Comment thread Lib/test/test_asyncore.py
@@ -431,9 +431,11 @@ def test_resource_warning(self):
def test_close_twice(self):
fd = os.open(support.TESTFN, os.O_RDONLY)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add something like: self.addCleanup(os.close, fd). It's enough to fix "./python -m test -R 3:3 test_asyncore".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed.

Comment thread Lib/test/test_asyncore.py
f.close()
os.close(f.fd) # file_wrapper dupped fd
with self.assertRaises(OSError):
f.close()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add this test here:

self.assertEqual(f.fileno(), -1)

To test your fix.

Comment thread Lib/test/test_asyncore.py
with self.assertRaises(OSError):
f.close()

self.assertEqual(f.fd, -1)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Haypo isn't this ^^^^ good enough?

Since file_wrapper.fd is not documented, maybe we should replace f.fd with f.fileno()? Do you want to add this change to the patch?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I missed it :-) It's enough.

@vstinner vstinner merged commit c648a93 into python:master Jul 24, 2017
@vstinner
Copy link
Copy Markdown
Member

Do you want to backport your fix to 3.5 and 3.6?

@vstinner
Copy link
Copy Markdown
Member

(ah, and 2.7 too according your bpo.)

@nirs
Copy link
Copy Markdown
Contributor Author

nirs commented Jul 24, 2017

@Haypo , I'll send backports later this week, thanks!

@nirs nirs deleted the double-close branch July 24, 2017 21:24
nirs added a commit to nirs/cpython that referenced this pull request Jul 26, 2017
* bpo-30980: Fix close test to fail

test_close_twice was not considering the fact that file_wrapper is
duping the file descriptor. Closing the original descriptor left the
duped one open, hiding the fact that close protection is not effective.

* bpo-30980: Fix double close protection

Invalidated self.fd before closing, handling correctly the case when
os.close raises.

* bpo-30980: Fix fd leak introduced in the fixed test
nirs added a commit to nirs/cpython that referenced this pull request Jul 26, 2017
* bpo-30980: Fix close test to fail

test_close_twice was not considering the fact that file_wrapper is
duping the file descriptor. Closing the original descriptor left the
duped one open, hiding the fact that close protection is not effective.

* bpo-30980: Fix double close protection

Invalidated self.fd before closing, handling correctly the case when
os.close raises.

* bpo-30980: Fix fd leak introduced in the fixed test
nirs added a commit to nirs/cpython that referenced this pull request Jul 26, 2017
* bpo-30980: Fix close test to fail

test_close_twice was not considering the fact that file_wrapper is
duping the file descriptor. Closing the original descriptor left the
duped one open, hiding the fact that close protection is not effective.

* bpo-30980: Fix double close protection

Invalidated self.fd before closing, handling correctly the case when
os.close raises.

* bpo-30980: Fix fd leak introduced in the fixed test
vstinner pushed a commit that referenced this pull request Jul 26, 2017
* bpo-30980: Fix close test to fail

test_close_twice was not considering the fact that file_wrapper is
duping the file descriptor. Closing the original descriptor left the
duped one open, hiding the fact that close protection is not effective.

* bpo-30980: Fix double close protection

Invalidated self.fd before closing, handling correctly the case when
os.close raises.

* bpo-30980: Fix fd leak introduced in the fixed test
vstinner pushed a commit that referenced this pull request Jul 26, 2017
* bpo-30980: Fix close test to fail

test_close_twice was not considering the fact that file_wrapper is
duping the file descriptor. Closing the original descriptor left the
duped one open, hiding the fact that close protection is not effective.

* bpo-30980: Fix double close protection

Invalidated self.fd before closing, handling correctly the case when
os.close raises.

* bpo-30980: Fix fd leak introduced in the fixed test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants